summaryrefslogtreecommitdiffstats
path: root/src/MachBunt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/MachBunt.cpp')
-rw-r--r--src/MachBunt.cpp890
1 files changed, 890 insertions, 0 deletions
diff --git a/src/MachBunt.cpp b/src/MachBunt.cpp
new file mode 100644
index 0000000..b20706b
--- /dev/null
+++ b/src/MachBunt.cpp
@@ -0,0 +1,890 @@
+/*
+ * SuSE window decoration for SuSE 9.1
+ * written by Adrian Schroeter <adrian@suse.de>
+ *
+ * copyright 2002 SuSE AG, GPL License
+ *
+ */
+
+#include "MachBunt.h"
+#include <kpixmapeffect.h>
+#include <kimageeffect.h>
+#include <kiconeffect.h>
+#include <kdrawutil.h>
+#include <klocale.h>
+#include <kconfig.h>
+#include <kstandarddirs.h>
+
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qdrawutil.h>
+#include <qdatetime.h>
+#include <qcursor.h>
+#include <qbitmap.h>
+#include <qimage.h>
+
+extern "C"
+{
+ KDecorationFactory *create_factory()
+ {
+ return new SuSEMachBunt::BuntFactory();
+ }
+}
+
+namespace SuSEMachBunt {
+
+#include "pixmaps.h"
+
+// [button number][inactive/active][std/mouseOver/buttonPressed][miniIcon]
+KPixmap buttonPixmap[BtnCount][2][3][2];
+bool titlebarResize, titlebarPlain,
+ titlebarLogo, titlebarSidebar,
+ titlebarNoPlainButtons;
+double titlebarLenseButtonFlare;
+
+static bool pixmaps_created = false;
+static QImage left_img[2][2];
+static QImage middle_img[2][2];
+static QImage right_img[2][2];
+static QImage text_img[2][2];
+static QImage bar_img[2][2];
+static QImage kroete_img[2][2];
+static QImage button_img[2][2];
+static QImage button_l_img[2][2];
+static QImage button_r_img[2][2];
+
+extern QColor *btnForeground;
+extern QPixmap *defaultPixmap;
+
+static QImage colorize(QImage img, const QColor &col1, const QColor &col2, float bright, float contrast )
+{
+ int rval, gval, bval, val, val2, i;
+ int pixels = (img.depth() > 8) ? img.width()*img.height()
+ : img.numColors();
+ unsigned int *data = img.depth() > 8 ? (unsigned int *) img.bits()
+ : (unsigned int *) img.colorTable();
+
+ for (i=0; i<pixels; i++)
+ {
+ val = static_cast<int>(qBlue(data[i]) * contrast);
+ val2 = static_cast<int>(qGreen(data[i]) * contrast);
+
+ rval = static_cast<int>( (val2*255*3 + (255-val2)*col2.red())/255 );
+ gval = static_cast<int>( (val2*255*3 + (255-val2)*col2.green())/255 );
+ bval = static_cast<int>( (val2*255*3 + (255-val2)*col2.blue())/255 );
+ rval = static_cast<int>( (val *rval + (255-val)*col1.red())/255 );
+ gval = static_cast<int>( (val *gval + (255-val)*col1.green())/255 );
+ bval = static_cast<int>( (val *bval + (255-val)*col1.blue())/255 );
+
+ if ( 255 < rval+qRed(data[i]) ) rval = 255;
+ else rval += qRed(data[i]);
+ if ( 255 < gval+qRed(data[i]) ) gval = 255;
+ else gval += qRed(data[i]);
+ if ( 255 < bval+qRed(data[i]) ) bval = 255;
+ else bval += qRed(data[i]);
+
+ if (bright != 1.0)
+ {
+ rval = static_cast<int>(bright*rval);
+ gval = static_cast<int>(bright*gval);
+ bval = static_cast<int>(bright*bval);
+ }
+
+ data[i] = qRgba(rval, gval, bval, qAlpha(data[i]));
+ }
+
+ return img;
+}
+
+KPixmap create_buttonPixmap( int x, int y, QPixmap _pix, QPixmap bg, int active, int mouse )
+{
+ QImage i;
+ KPixmap _p(QPixmap(x,y));
+ QPixmap t, pix;
+ QPainter p;
+
+ if ( _pix.isNull() )
+ pix = QPixmap(kdelogo);
+ else
+ pix = _pix;
+
+ p.begin(&_p);
+
+ if ( x != pix.width() || y != pix.height() ){
+ p.drawImage( 0, 0, bg.convertToImage().smoothScale(x,y) );
+ p.drawPixmap((x-pix.width())/2, (y-pix.height())/2, pix );
+ }else{
+ p.drawTiledPixmap(0, 0, x, y, bg );
+ p.drawPixmap(0, (y-pix.height())/2, pix );
+ }
+
+ p.end();
+
+ if ( !(mouse == 1 && titlebarPlain) && !(mouse == 0 && !titlebarPlain) ){ // not standard
+ i=_p;
+ if ( (mouse == 0 && titlebarPlain) || (mouse == 1 && !titlebarPlain) ){ // mouse over
+ _p.convertFromImage(KImageEffect::blend(Qt::white, i, 0.25 ));
+ }else{ // pressed
+ _p.convertFromImage(KImageEffect::blend(Qt::black, i, 0.25 ));
+ }
+
+ if ( mouse == 2 ) { // pressed
+ i=_p;
+ p.begin(&_p);
+ p.drawImage( 0, 2, i, 0, 0, i.width(), i.height()-2 );
+ p.end();
+ }
+ }
+
+ return _p;
+}
+
+QImage image_convert( const char **b, int h){
+ QPixmap p(b);
+ QImage i;
+ i = p.convertToImage();
+ if ( p.height()!=h )
+ i = i.smoothScale((p.width()*h)/p.height(),h);
+ return i;
+}
+
+static void create_pixmaps( )
+{
+ if(pixmaps_created)
+ return;
+
+ pixmaps_created = true;
+
+ for ( int m=0; m<2; m++ )
+ for ( int i=0; i<2; i++){
+ QColor ctb = KDecoration::options()->color(KDecoration::ColorTitleBar,i);
+ QColor ctbB = KDecoration::options()->color(KDecoration::ColorTitleBlend,i);
+ left_img[i][m] = colorize(image_convert(left_xpm, m ? 12 : PIX_HEIGHT) , ctb,
+ ctbB, 0.75 , 0.75 );
+ right_img[i][m] = colorize(image_convert(right_xpm, m ? 12 : PIX_HEIGHT) , ctb,
+ ctbB, 1.0 , 1.0 );
+ middle_img[i][m] = colorize(image_convert(middle_xpm, m ? 12 : PIX_HEIGHT), ctb,
+ ctbB, 1.0 , 1.0 );
+ text_img[i][m] = colorize(image_convert(middle_xpm, m ? 12 : PIX_HEIGHT), ctb,
+ ctbB, 0.75 , 0.75 );
+ kroete_img[i][m] = colorize(image_convert(kroete_xpm, m ? 12 : PIX_HEIGHT), ctb,
+ ctbB, 1.0 , 1.0 );
+ bar_img[i][m] = colorize(image_convert(bar_xpm, m ? 12 : PIX_HEIGHT), ctb,
+ ctbB, 1.0 , 1.0 );
+ button_img[i][m] = colorize(image_convert(middle_button_xpm, m ? 12 : PIX_HEIGHT), ctb,
+ ctbB, 1.0 , 1.0 );
+ button_l_img[i][m] = colorize(image_convert(middle_button_left_xpm, m ? 12 : PIX_HEIGHT), ctb,
+ ctbB, 1.0 , 1.0 );
+ button_r_img[i][m] = colorize(image_convert(middle_button_right_xpm, m ? 12 : PIX_HEIGHT), ctb,
+ ctbB, 1.0 , 1.0 );
+ }
+
+ for ( int m=0; m<2; m++ )
+ for ( int M=0; M<3; M++ )
+ for ( int a=0; a<2; a++ ){
+ buttonPixmap[0][a][M][m] = create_buttonPixmap( m ? 12 : PIX_HEIGHT, m ? 12 : PIX_HEIGHT, QPixmap(kdelogo), button_img[a][m], a, M );
+ buttonPixmap[1][a][M][m] = create_buttonPixmap( m ? 12 : PIX_HEIGHT, m ? 12 : PIX_HEIGHT, QPixmap(sticky_xpm), button_img[a][m], a, M );
+ buttonPixmap[2][a][M][m] = create_buttonPixmap( m ? 12 : PIX_HEIGHT, m ? 12 : PIX_HEIGHT, QPixmap(question_xpm), button_img[a][m], a, M );
+ buttonPixmap[3][a][M][m] = create_buttonPixmap( m ? 12 : PIX_HEIGHT, m ? 12 : PIX_HEIGHT, QPixmap(iconify_xpm), button_img[a][m], a, M );
+ buttonPixmap[4][a][M][m] = create_buttonPixmap( m ? 12 : PIX_HEIGHT, m ? 12 : PIX_HEIGHT, QPixmap(maximze_xpm), button_img[a][m], a, M );
+ QPixmap i(button_img[a][m]);
+ QPainter p(&i);
+ p.drawPixmap(button_img[a][m].width()-right_img[a][m].width()+BORDER_RIGHT, 0, right_img[a][m]);
+ p.end();
+ buttonPixmap[5][a][M][m] = create_buttonPixmap( m ? 12 : PIX_HEIGHT, m ? 12 : PIX_HEIGHT, QPixmap(close_xpm), i, a, M );
+ }
+
+ // Make sure button pixmaps contrast with the current colour scheme.
+ if(qGray(KDecoration::options()->color(KDecoration::ColorTitleBar,true).rgb()) > 127)
+ btnForeground = new QColor(Qt::black);
+ else
+ btnForeground = new QColor(Qt::white);
+}
+
+void delete_pixmaps()
+{
+ delete btnForeground;
+
+ pixmaps_created = false;
+}
+
+MachBunt::MachBunt(KDecorationBridge* bridge, KDecorationFactory* factory)
+ : KDecoration(bridge, factory), windowLayout(0)
+{
+
+ lastButtonWidth = 0;
+ buttonPressedPosition.setX( -1 );
+ for ( int i=0; i < BtnCount; i++ )
+ button[i]=0;
+
+ hiddenItems = false;
+}
+
+MachBunt::~MachBunt()
+{
+}
+
+void MachBunt::init()
+{
+ if ( isTool() ) {
+ titleHeight = 12;
+ smallButtons = true;
+ } else {
+ titleHeight = PIX_HEIGHT;
+ smallButtons = false;
+ }
+
+ createMainWidget(WNoAutoErase);
+ widget()->installEventFilter( this );
+ widget()->setBackgroundMode(NoBackground);
+
+ KConfig c("kwinMachBuntrc");
+ c.setGroup("General");
+ titlebarResize = c.readBoolEntry("TitleBarResize", true);
+ titlebarLogo = c.readBoolEntry("TitleBarLogo", true);
+ titlebarPlain = c.readBoolEntry("TitleBarPlain", true);
+ titlebarNoPlainButtons = c.readBoolEntry("TitleBarNoPlainButtons", false);
+ titlebarSidebar = c.readBoolEntry("TitleBarSideBar", false);
+ titlebarLenseButtonFlare = c.readDoubleNumEntry("titlebarLenseButtonFlare", 1.7);
+ defaultPixmap = new QPixmap(kdelogo);
+ create_pixmaps();
+ createButtons();
+
+ doLayout();
+}
+
+void MachBunt::createButtons()
+{
+ if ( !button[BtnMenu] )
+ button[BtnMenu] = new MachBuntButton(this, "menu", BtnMenu, text_img[0][smallButtons], text_img[1][smallButtons], smallButtons, i18n("Menu"));
+// if ( !button[BtnSticky] )
+// button[BtnSticky] = new MachBuntButton(this, "sticky", BtnSticky, middle_img[0][smallButtons], middle_img[1][smallButtons], smallButtons, i18n("Sticky"));
+ if ( !button[BtnHelp] )
+ button[BtnHelp]= new MachBuntButton(this, "help", BtnHelp, middle_img[0][smallButtons], middle_img[1][smallButtons], smallButtons, i18n("Help"));
+ if ( !button[BtnIconify] )
+ button[BtnIconify] = new MachBuntButton(this, "iconify", BtnIconify, middle_img[0][smallButtons], middle_img[1][smallButtons], smallButtons, i18n("Minimize"));
+ if ( !button[BtnMax] )
+ button[BtnMax] = new MachBuntButton(this, "maximize", BtnMax, middle_img[0][smallButtons], middle_img[1][smallButtons], smallButtons, i18n("Maximize"));
+ if ( !button[BtnClose] )
+ button[BtnClose] = new MachBuntButton(this, "close", BtnClose, middle_img[0][smallButtons], middle_img[1][smallButtons], smallButtons, i18n("Close"));
+
+ // 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( minimize() ));
+ connect( button[BtnMax], SIGNAL( clicked() ), this, SLOT( slotMaximize() ));
+ for ( int i=0; i < BtnCount; i++ )
+ if ( button[i] ){
+ connect( button[i], SIGNAL(shapeMe(int)),this, SLOT(doShape(int)));
+ connect( button[i], SIGNAL(pressed()),this, SLOT(buttonPressed()));
+ connect( button[i], SIGNAL(released()),this, SLOT(buttonReleased()));
+ connect( button[i], SIGNAL(mousePressedMove(QMouseEvent*)),this, SLOT(mouseMoveOnButtonPressed(QMouseEvent*)));
+ }
+
+ connect( button[BtnHelp], SIGNAL( clicked() ), this, SLOT( showContextHelp() ));
+
+ // Hide buttons which are not required
+ // We can un-hide them if required later
+ if ( !isMinimizable() )
+ button[BtnIconify]->hide();
+ if ( !isMaximizable() )
+ button[BtnMax]->hide();
+ if ( !providesContextHelp())
+ button[BtnHelp]->hide();
+
+ // Make sure that the menu button uses the correct mini-icon
+ iconChange();
+ maximizeChange();
+ desktopChange();
+}
+
+void MachBunt::reset( unsigned long changed )
+{
+ for(int i = 0; i < BtnCount; i++)
+ if(button[i])
+ button[i]->reset( changed );
+ widget()->repaint();
+}
+
+int MachBunt::mapButton( const QChar &c)
+{
+ switch (c.latin1())
+ {
+ case 'M':
+ return BtnMenu;
+ case 'S':
+ return BtnSticky;
+ case 'H': // Help
+ return BtnHelp;
+ case 'I': // Minimize
+ return BtnIconify;
+ case 'A': // Maximize
+ return BtnMax;
+ case 'X': // Close
+ return BtnClose;
+ }
+ // something went wrong
+ qDebug("unknown Button to map \"%c\"", c.latin1() );
+ return -1;
+}
+
+void MachBunt::doLayout()
+{
+ delete windowLayout;
+
+ windowLayout = new QVBoxLayout(widget(), 0, 0);
+ titlebar = new QSpacerItem ( 0, titleHeight, QSizePolicy::Expanding,
+ QSizePolicy::Fixed);
+ QBoxLayout *topLayout = new QBoxLayout(windowLayout, QBoxLayout::LeftToRight, 0, 0);
+#if 0
+ bool first_left = true;
+ for ( unsigned int i = 0; i <options()->titleButtonsLeft().length(); i++)
+ {
+ int b = mapButton(options()->titleButtonsLeft()[i]);
+ if ( b>=0 ){
+ topLayout->addWidget(button[b], Qt::AlignVCenter);
+ topLayout->setStretchFactor(button[b], 0);
+ button[b]->setFixedSize(titleHeight, titleHeight);
+ if( first_left )
+ {
+ first_left = false;
+ button[b]->setPosition( ButtonLeft );
+ }
+ }
+ }
+
+ topLayout->addItem(titlebar);
+
+#else
+ topLayout->addWidget(button[BtnMenu], Qt::AlignVCenter);
+ topLayout->setStretchFactor(button[BtnMenu], 0);
+ button[BtnMenu]->setFixedSize(titleHeight, titleHeight);
+ button[BtnMenu]->setPosition( ButtonLeft );
+
+ topLayout->addItem(titlebar);
+
+ topLayout->addWidget(button[BtnHelp], Qt::AlignVCenter);
+ topLayout->setStretchFactor(button[BtnHelp], 0);
+ button[BtnHelp]->setFixedSize(titleHeight, titleHeight);
+
+ topLayout->addWidget(button[BtnIconify], Qt::AlignVCenter);
+ topLayout->setStretchFactor(button[BtnIconify], 0);
+ button[BtnIconify]->setFixedSize(titleHeight, titleHeight);
+
+ topLayout->addWidget(button[BtnMax], Qt::AlignVCenter);
+ topLayout->setStretchFactor(button[BtnMax], 0);
+ button[BtnMax]->setFixedSize(titleHeight, titleHeight);
+
+ topLayout->addWidget(button[BtnClose], Qt::AlignVCenter);
+ topLayout->setStretchFactor(button[BtnClose], 0);
+ button[BtnClose]->setFixedSize(titleHeight, titleHeight);
+ button[BtnClose]->setPosition( ButtonRight );
+
+ if ( !isMinimizable() )
+ button[BtnIconify]->hide();
+ if ( !isMaximizable() )
+ button[BtnMax]->hide();
+#endif
+#if 0
+ MachBuntButton* last_right = NULL;
+ for ( unsigned int i = 0; i <options()->titleButtonsRight().length(); i++)
+ {
+ int b = mapButton(options()->titleButtonsRight()[i]);
+ if ( b>=0 ){
+ topLayout->addWidget(button[b], Qt::AlignVCenter);
+ topLayout->setStretchFactor(button[b], 0);
+ button[b]->setFixedSize(titleHeight, titleHeight);
+ last_right = button[b];
+ }
+ }
+ if( last_right )
+ last_right->setPosition( ButtonRight );
+#endif
+
+ QHBoxLayout * midLayout = new QHBoxLayout(windowLayout, 0, 0);
+ midLayout->addSpacing(BORDER_LEFT);
+ if( isPreview())
+ midLayout->addWidget(new QLabel( i18n( "<center><b>MachBunt</b></center>" ), widget()));
+ else
+ midLayout->addItem( new QSpacerItem( 0, 0 )); // no widget in the middle
+ midLayout->addSpacing(BORDER_RIGHT);
+
+ windowLayout->addSpacing(BORDER_BOTTOM);
+ windowLayout->setStretchFactor(topLayout, 0);
+ windowLayout->setStretchFactor(midLayout, 1);
+}
+
+void MachBunt::borders(int& left, int& right, int& top, int& bottom) const
+{
+ left = BORDER_LEFT;
+ right = BORDER_RIGHT;
+ top = titleHeight;
+ bottom = BORDER_BOTTOM;
+}
+
+void MachBunt::mouseMoveOnButtonPressed( QMouseEvent *e )
+{
+#if 0
+ if ( buttonPressedPosition.x() >= 0 ){
+ QPoint p( buttonPressedPosition.x() - geometry().x(),
+ buttonPressedPosition.y() - geometry().y());
+
+ if ( mousePosition(p) == KDecoration::TopLeft ||
+ mousePosition(p) == KDecoration::TopRight )
+ performMouseCommand(Options::MouseResize, QCursor::pos());
+ else if ( mousePosition(p) == KDecoration::Top ){
+ QPoint m(geometry().x()+geometry().width()/2, geometry().y());
+ performMouseCommand(Options::MouseResize, m );
+ }
+ buttonPressedPosition.setX( -1 );
+ }
+
+ KDecoration::mouseMoveEvent(e);
+#endif
+}
+
+void MachBunt::buttonPressed()
+{
+ QPoint p( QCursor::pos().x() - geometry().x(),
+ QCursor::pos().y() - geometry().y());
+
+ if ( mousePosition(p) == KDecorationDefines::PositionTopLeft ||
+ mousePosition(p) == KDecorationDefines::PositionTopRight ||
+ mousePosition(p) == KDecorationDefines::PositionTop )
+ buttonPressedPosition = QCursor::pos();
+}
+
+void MachBunt::buttonReleased()
+{
+ buttonPressedPosition.setX( -1 );
+// keyPressEvent( Key_Escape );
+}
+
+ KDecoration::Position
+MachBunt::mousePosition(const QPoint & p) const
+{
+ int x = p.x();
+ int y = p.y();
+
+ if ( y < titleHeight ){
+ if ( x < BUTTON_RESIZE_SIZE )
+ return KDecorationDefines::PositionTopLeft;
+ if ( x > width() - 1 - BUTTON_RESIZE_SIZE )
+ return KDecorationDefines::PositionTopRight;
+ }
+
+ if ( titlebarResize ){
+ if ( ( ! (x < BUTTON_RESIZE_SIZE || x > width() - 1 - BUTTON_RESIZE_SIZE) )
+ && (y < TOP_RESIZE_HEIGHT ))
+ {
+ if ( titlebarResize==true )
+ return KDecorationDefines::PositionTop;
+ else
+ return KDecorationDefines::PositionCenter;
+ }
+ }
+ return KDecoration::mousePosition(p);
+}
+
+void MachBunt::slotMaximize()
+{
+ if ( button[BtnMax]->last_button == MidButton )
+ maximize(maximizeMode() ^ MaximizeVertical );
+ else if ( button[BtnMax]->last_button == RightButton )
+ maximize(maximizeMode() ^ MaximizeHorizontal );
+ else
+ maximize(maximizeMode() == MaximizeFull ? MaximizeRestore : MaximizeFull);
+}
+
+void MachBunt::resize( const QSize& s )
+{
+ widget()->resize( s );
+}
+
+QSize MachBunt::minimumSize() const
+{
+ return QSize( 200, 50 );
+}
+
+const int SUPPORTED_WINDOW_TYPES_MASK = NET::NormalMask | NET::DesktopMask | NET::DockMask
+ | NET::ToolbarMask | NET::MenuMask | NET::DialogMask | NET::OverrideMask | NET::TopMenuMask
+ | NET::UtilityMask | NET::SplashMask;
+
+bool MachBunt::isTool()
+{
+ NET::WindowType type = windowType( SUPPORTED_WINDOW_TYPES_MASK );
+ return ((type==NET::Toolbar)||(type==NET::NET::Utility)||(type==NET::Menu));
+}
+
+bool MachBunt::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;
+ default:
+ break;
+ }
+ return false;
+}
+
+void MachBunt::desktopChange()
+{
+ emit(oadChange(isOnAllDesktops()));
+}
+
+KDecoration* BuntFactory::createDecoration( KDecorationBridge* b )
+{
+ return(new MachBunt(b, this));
+}
+
+bool BuntFactory::reset(unsigned long changed)
+{
+ // Do we need to "hit the wooden hammer" ?
+ bool needHardReset = false;
+ if (changed & (SettingDecoration | SettingFont | SettingButtons | SettingBorder))
+ {
+ needHardReset = true;
+ }
+ if( changed & SettingColors )
+ { // pixmaps need to be recreated
+ delete_pixmaps();
+ create_pixmaps();
+ }
+
+ if (needHardReset) {
+ return true;
+ } else {
+ resetDecorations(changed);
+ return false;
+ }
+}
+
+QValueList< BuntFactory::BorderSize > BuntFactory::borderSizes() const
+{ // the list must be sorted
+ return QValueList< BorderSize >() << BorderNormal;
+ // TODO << BorderLarge << BorderVeryLarge << BorderHuge << BorderVeryHuge << BorderOversized;
+}
+
+void MachBunt::resizeEvent( QResizeEvent*)
+{
+ doShape();
+
+ calcHiddenButtons();
+ widget()->repaint();
+#if 0
+ for ( int i=0; i < BtnCount; i++ )
+ if ( button[i] )
+ button[i]->reset(0);
+
+ 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( widget(), new QPaintEvent( titlebar->geometry(), FALSE ) );
+ }
+ }
+#endif
+}
+
+
+void MachBunt::captionChange()
+{
+ widget()->repaint( titlebar->geometry(), false );
+}
+
+void MachBunt::iconChange()
+{
+ button[BtnMenu]->setPixmap( icon().pixmap( QIconSet::Small, QIconSet::Normal ));
+
+ if (button[BtnMenu]->isVisible())
+ button[BtnMenu]->repaint(false);
+}
+
+
+void MachBunt::paintEvent( QPaintEvent *pe )
+{
+// bool hicolor = QPixmap::defaultDepth() > 8;
+ int fontoffset = 1;
+
+ QPainter p(widget());
+ p.setClipRegion(pe->region());
+
+ // Obtain widget bounds.
+ QRect r(widget()->rect());
+ int i;
+ int x = r.x();
+ int y = r.y();
+ int x2 = r.width()-1;
+ int y2 = r.height()-1;
+ int w = r.width();
+ int ps = smallButtons ? PIX_SIDE/2 : PIX_SIDE;
+
+ QColorGroup g = options()->colorGroup(KDecorationDefines::ColorFrame, isActive());
+
+ p.setPen( g.dark() );
+ // the dark outer drawings
+ p.drawLine(x, y+PIX_CORNER_RADIUS+2*BORDER_LEFT, x, y2);
+ p.drawLine(x2, y+PIX_CORNER_RADIUS+2*BORDER_LEFT, x2, y2);
+ p.drawLine(x, y2 , x2, y2);
+ // the dark diagonals beside titlebar
+ p.drawLine(x, y+PIX_CORNER_RADIUS+2*BORDER_LEFT, x+BORDER_LEFT, y+PIX_CORNER_RADIUS+BORDER_LEFT);
+ p.drawLine(x2, y+PIX_CORNER_RADIUS+2*BORDER_LEFT, x2-BORDER_LEFT, y+PIX_CORNER_RADIUS+BORDER_LEFT);
+ p.setPen( g.light() );
+ if ( titlebarSidebar ){
+ for ( i=1; i<BORDER_LEFT; i++)
+ p.drawLine(x+i, y+PIX_CORNER_RADIUS+2*BORDER_LEFT-i+1, x+i, y2-1);
+ for ( i=1; i<BORDER_RIGHT; i++)
+ p.drawLine(x2-i, y+PIX_CORNER_RADIUS+2*BORDER_LEFT-i+1, x2-i, y2-1);
+ }else{
+ for ( i=1; i<BORDER_LEFT; i++)
+ p.drawLine(x+i, titleHeight, x+i, y2-1);
+ for ( i=1; i<BORDER_RIGHT; i++)
+ p.drawLine(x2-i, titleHeight, x2-i, y2-1);
+ }
+ for ( i=1; i<BORDER_BOTTOM; i++)
+ p.drawLine(x+1,y2-i, w-2, y2-i);
+
+ // draw the title bar.
+ r = titlebar->geometry();
+// QFontMetrics fm(options()->font(true));
+
+ KPixmap titleBuffer;
+ if ( titlebarSidebar )
+ titleBuffer.resize(w-BORDER_LEFT-BORDER_RIGHT, titleHeight);
+ else
+ titleBuffer.resize(w, titleHeight);
+ KIconEffect kie;
+
+ QPainter p2( &titleBuffer, widget());
+
+ p2.drawTiledPixmap( ps, 0, titleBuffer.width()-2*ps, titleHeight, middle_img[isActive()][smallButtons]);
+ p2.drawTiledPixmap( 0, 0, ps, titleHeight, left_img[isActive()][smallButtons]);
+ p2.drawTiledPixmap( titleBuffer.width()-ps, 0, ps, titleHeight, right_img[isActive()][smallButtons]);
+
+ int l;
+ if ( button[BtnHelp] && button[BtnHelp]->isShown() )
+ l=button[BtnHelp]->x();
+ else if ( button[BtnIconify]->isShown() )
+ l=button[BtnIconify]->x();
+ else if ( button[BtnMax]->isShown() )
+ l=button[BtnMax]->x();
+ else if ( button[BtnClose]->isShown() )
+ l=button[BtnClose]->x();
+ else
+ l=0;
+
+ p2.drawTiledPixmap(l-titleHeight/2, 0, titleHeight-(titleHeight/2), titleHeight, button_img[isActive()][smallButtons], titleHeight/2, 0);
+
+ // Reduce the font size and weight for toolwindows.
+ QFont font = options()->font(true);
+ if ( smallButtons )
+ {
+ font.setPointSize( font.pointSize() - 2 );
+ font.setWeight( QFont::Normal );
+ fontoffset = 0;
+ }
+ p2.setFont( font );
+ p2.setPen( options()->color(KDecorationDefines::ColorFont, isActive() ));
+ w = p2.fontMetrics().width(caption())+2*TEXT_BORDER;
+ if ( w > r.width()-3-button_l_img[0][smallButtons].width()-bar_img[0][smallButtons].width() ) w=r.width()-3-button_l_img[0][smallButtons].width()-bar_img[0][smallButtons].width();
+ p2.drawTiledPixmap( r.x()-TEXT_BORDER-ps, 0, w+ps+2*TEXT_BORDER+3, titleHeight , text_img[isActive()][smallButtons]);
+ p2.drawPixmap(r.x()+w+TEXT_BORDER, 0, bar_img[isActive()][smallButtons]);
+ if ( titlebarLogo && isActive() && r.x()+w+kroete_img[0][smallButtons].width() < r.width() )
+ p2.drawTiledPixmap( r.x()+w+bar_img[0][smallButtons].width(), 0, kroete_img[0][smallButtons].width(), titleHeight, kroete_img[isActive()][smallButtons]);
+ p2.drawText( r.x(), fontoffset, w+TEXT_BORDER, r.height()-1, AlignLeft | AlignVCenter, caption() );
+
+ p2.end();
+
+ if ( titlebarSidebar )
+ p.drawPixmap( BORDER_LEFT, 0, titleBuffer );
+ else
+ p.drawPixmap( 0, 0, titleBuffer );
+}
+
+void MachBunt::showEvent(QShowEvent *)
+{
+ doShape();
+ widget()->repaint();
+}
+
+void MachBunt::mouseDoubleClickEvent( QMouseEvent * e )
+{
+ if (titlebar->geometry().contains( e->pos() ) )
+ titlebarDblClickOperation();
+}
+
+
+void MachBunt::maximizeChange()
+{
+// button[BtnMax]->setBitmap(m ? minmax_bits : maximize_bits);
+ button[BtnMax]->setTipText( (maximizeMode()==MaximizeFull) ? i18n("Restore") : i18n("Maximize"));
+}
+
+
+void MachBunt::activeChange()
+{
+ for(int i=0; i < BtnCount; i++)
+ {
+ if(button[i])
+ button[i]->repaint();
+ }
+
+ widget()->repaint();
+}
+
+
+void MachBunt::calcHiddenButtons()
+{
+ // order of hiding is help, maximize, minimize, close, then menu;
+ int minWidth = 32 + titleHeight*4 + (providesContextHelp() ? titleHeight*2 : titleHeight );
+
+ if(lastButtonWidth > width()) // Shrinking
+ {
+ lastButtonWidth = width();
+ if(width() < minWidth)
+ {
+ hiddenItems = true;
+
+ for(int i = 0; i < BtnCount; 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 = titleHeight*3;
+
+ for(int i = BtnCount - 1; i >= 0; 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 MachBunt::menuButtonPressed()
+{
+ // KS - move the menu left by 3 pixels, and down 2 pixels.
+ QPoint menupoint ( button[BtnMenu]->rect().bottomLeft().x()-3,
+ button[BtnMenu]->rect().bottomLeft().y()+2 );
+ KDecorationFactory* f = factory();
+ showWindowMenu( button[BtnMenu]->mapToGlobal( menupoint ));
+ if( !f->exists( this )) // 'this' was destroyed
+ return;
+ button[BtnMenu]->setDown(false);
+}
+
+void MachBunt::doShape(int x)
+{
+ QRegion mask(0, 0, width(), height());
+
+ int bWidth = smallButtons ? 12 : PIX_HEIGHT;
+ int i, bl=0, br=0, p=0;
+ int r(width());
+ if ( titlebarSidebar ){
+ bl=BORDER_LEFT;
+ br=BORDER_RIGHT;
+ // is the right button pressed ?
+ if ( x >= (r - br - bWidth) )
+ p=2;
+ }
+
+ mask -= QRegion(0, 0, bl+3, 1);
+ mask -= QRegion(0, 1, bl+1, 1);
+
+ // Remove top-right corner.
+ if ( smallButtons ){
+ mask -= QRegion(r-3-br, 0, 3+br, 1+p);
+ mask -= QRegion(r-2-br, 1, 2+br, 1+p);
+ mask -= QRegion(r-1-br, 2, 1+br, 1+p);
+ }else{
+ mask -= QRegion(r-7-br, 0, 7+br, 1+p);
+ mask -= QRegion(r-5-br, 1, 5+br, 1+p);
+ mask -= QRegion(r-4-br, 2, 4+br, 1+p);
+ mask -= QRegion(r-3-br, 3, 3+br, 1+p);
+ mask -= QRegion(r-2-br, 4, 2+br, 1+p);
+ mask -= QRegion(r-1-br, 5, 1+br, 2+p);
+ }
+ for ( i=0; i<br; i++)
+ mask -= QRegion(r-i-1, 0, 1, PIX_CORNER_RADIUS+bl+br-i);
+
+ // the buttons
+ for ( i=0; i<BtnCount; i++){
+ if ( button[i] && button[i]->isShown() ){
+ // top left corner of this button and right part of the button before
+ mask -= QRegion( button[i]->x() - 3, 0, 4, 1 );
+ mask -= QRegion( button[i]->x() - 1, 0, 1, 2 );
+ }
+ }
+
+ // the pressed button
+ if ( x != 0 ){
+ mask -= QRegion( x, 0, bWidth, 2 );
+ mask -= QRegion( x, 0, 1, 3 );
+ mask -= QRegion( x + bWidth -3 , 0, 3, 3 );
+ mask -= QRegion( x + bWidth -1 , 0, 1, 4 );
+ }
+
+ setMask(mask);
+}
+
+}
+
+#include "MachBunt.moc"
+// vim: ts=4