diff options
Diffstat (limited to 'src/MachBunt.cpp')
-rw-r--r-- | src/MachBunt.cpp | 890 |
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 |