00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifdef HAVE_CONFIG_H
00027 #include "config.h"
00028 #endif
00029
00030 #include "kstyle.h"
00031
00032 #include <qapplication.h>
00033 #include <qbitmap.h>
00034 #include <qmetaobject.h>
00035 #include <qcleanuphandler.h>
00036 #include <qmap.h>
00037 #include <qimage.h>
00038 #include <qlistview.h>
00039 #include <qmenubar.h>
00040 #include <qpainter.h>
00041 #include <qpixmap.h>
00042 #include <qpopupmenu.h>
00043 #include <qprogressbar.h>
00044 #include <qscrollbar.h>
00045 #include <qsettings.h>
00046 #include <qslider.h>
00047 #include <qstylefactory.h>
00048 #include <qtabbar.h>
00049 #include <qtoolbar.h>
00050
00051 #include <kpixmap.h>
00052 #include <kpixmapeffect.h>
00053 #include <kimageeffect.h>
00054
00055 #ifdef Q_WS_X11
00056 # include <X11/Xlib.h>
00057 # ifdef HAVE_XRENDER
00058 # include <X11/extensions/Xrender.h>
00059 extern bool qt_use_xrender;
00060 # endif
00061 #else
00062 #undef HAVE_XRENDER
00063 #endif
00064
00065
00066 #include <limits.h>
00067
00068 namespace
00069 {
00070
00071 enum TransparencyEngine {
00072 Disabled = 0,
00073 SoftwareTint,
00074 SoftwareBlend,
00075 XRender
00076 };
00077
00078
00079 struct ShadowElements {
00080 QWidget* w1;
00081 QWidget* w2;
00082 };
00083 typedef QMap<const QWidget*,ShadowElements> ShadowMap;
00084 static ShadowMap *_shadowMap = 0;
00085 QSingleCleanupHandler<ShadowMap> cleanupShadowMap;
00086 ShadowMap &shadowMap() {
00087 if ( !_shadowMap ) {
00088 _shadowMap = new ShadowMap;
00089 cleanupShadowMap.set( &_shadowMap );
00090 }
00091 return *_shadowMap;
00092 }
00093
00094
00095
00096
00097 const double top_right_corner[16] =
00098 { 0.949, 0.965, 0.980, 0.992,
00099 0.851, 0.890, 0.945, 0.980,
00100 0.706, 0.780, 0.890, 0.960,
00101 0.608, 0.706, 0.851, 0.949 };
00102
00103 const double bottom_right_corner[16] =
00104 { 0.608, 0.706, 0.851, 0.949,
00105 0.706, 0.780, 0.890, 0.960,
00106 0.851, 0.890, 0.945, 0.980,
00107 0.949, 0.965, 0.980, 0.992 };
00108
00109 const double bottom_left_corner[16] =
00110 { 0.949, 0.851, 0.706, 0.608,
00111 0.965, 0.890, 0.780, 0.706,
00112 0.980, 0.945, 0.890, 0.851,
00113 0.992, 0.980, 0.960, 0.949 };
00114
00115 const double shadow_strip[4] =
00116 { 0.565, 0.675, 0.835, 0.945 };
00117
00118 static bool useDropShadow(QWidget* w)
00119 {
00120 return w && w->metaObject() &&
00121 w->metaObject()->findProperty("KStyleMenuDropShadow") != -1;
00122 }
00123 }
00124
00125 namespace
00126 {
00127 class TransparencyHandler : public QObject
00128 {
00129 public:
00130 TransparencyHandler(KStyle* style, TransparencyEngine tEngine,
00131 float menuOpacity, bool useDropShadow);
00132 ~TransparencyHandler();
00133 bool eventFilter(QObject* object, QEvent* event);
00134
00135 protected:
00136 void blendToColor(const QColor &col);
00137 void blendToPixmap(const QColorGroup &cg, const QWidget* p);
00138 #ifdef HAVE_XRENDER
00139 void XRenderBlendToPixmap(const QWidget* p);
00140 #endif
00141 void createShadowWindows(const QWidget* p);
00142 void removeShadowWindows(const QWidget* p);
00143 void rightShadow(QImage& dst);
00144 void bottomShadow(QImage& dst);
00145 private:
00146 bool dropShadow;
00147 float opacity;
00148 QPixmap pix;
00149 KStyle* kstyle;
00150 TransparencyEngine te;
00151 };
00152 }
00153
00154 struct KStylePrivate
00155 {
00156 bool highcolor : 1;
00157 bool useFilledFrameWorkaround : 1;
00158 bool etchDisabledText : 1;
00159 bool scrollablePopupmenus : 1;
00160 bool menuAltKeyNavigation : 1;
00161 bool menuDropShadow : 1;
00162 bool sloppySubMenus : 1;
00163 bool semiTransparentRubberband : 1;
00164 int popupMenuDelay;
00165 float menuOpacity;
00166
00167 TransparencyEngine transparencyEngine;
00168 KStyle::KStyleScrollBarType scrollbarType;
00169 TransparencyHandler* menuHandler;
00170 KStyle::KStyleFlags flags;
00171
00172
00173 QBitmap *verticalLine;
00174 QBitmap *horizontalLine;
00175 };
00176
00177
00178
00179
00180 KStyle::KStyle( KStyleFlags flags, KStyleScrollBarType sbtype )
00181 : QCommonStyle(), d(new KStylePrivate)
00182 {
00183 d->flags = flags;
00184 bool useMenuTransparency = (flags & AllowMenuTransparency);
00185 d->useFilledFrameWorkaround = (flags & FilledFrameWorkaround);
00186 d->scrollbarType = sbtype;
00187 d->highcolor = QPixmap::defaultDepth() > 8;
00188
00189
00190 QSettings settings;
00191 d->popupMenuDelay = settings.readNumEntry ("/KStyle/Settings/PopupMenuDelay", 256);
00192 d->sloppySubMenus = settings.readBoolEntry("/KStyle/Settings/SloppySubMenus", false);
00193 d->etchDisabledText = settings.readBoolEntry("/KStyle/Settings/EtchDisabledText", true);
00194 d->menuAltKeyNavigation = settings.readBoolEntry("/KStyle/Settings/MenuAltKeyNavigation", true);
00195 d->scrollablePopupmenus = settings.readBoolEntry("/KStyle/Settings/ScrollablePopupMenus", false);
00196 d->menuDropShadow = settings.readBoolEntry("/KStyle/Settings/MenuDropShadow", false);
00197 d->semiTransparentRubberband = settings.readBoolEntry("/KStyle/Settings/SemiTransparentRubberband", false);
00198 d->menuHandler = NULL;
00199
00200 if (useMenuTransparency) {
00201 QString effectEngine = settings.readEntry("/KStyle/Settings/MenuTransparencyEngine", "Disabled");
00202
00203 #ifdef HAVE_XRENDER
00204 if (effectEngine == "XRender")
00205 d->transparencyEngine = XRender;
00206 #else
00207 if (effectEngine == "XRender")
00208 d->transparencyEngine = SoftwareBlend;
00209 #endif
00210 else if (effectEngine == "SoftwareBlend")
00211 d->transparencyEngine = SoftwareBlend;
00212 else if (effectEngine == "SoftwareTint")
00213 d->transparencyEngine = SoftwareTint;
00214 else
00215 d->transparencyEngine = Disabled;
00216
00217 if (d->transparencyEngine != Disabled) {
00218
00219 d->menuOpacity = settings.readDoubleEntry("/KStyle/Settings/MenuOpacity", 0.90);
00220 d->menuHandler = new TransparencyHandler(this, d->transparencyEngine,
00221 d->menuOpacity, d->menuDropShadow);
00222 }
00223 }
00224
00225 d->verticalLine = 0;
00226 d->horizontalLine = 0;
00227
00228
00229 if (!d->menuHandler && d->menuDropShadow)
00230 d->menuHandler = new TransparencyHandler(this, Disabled, 1.0, d->menuDropShadow);
00231 }
00232
00233
00234 KStyle::~KStyle()
00235 {
00236 delete d->verticalLine;
00237 delete d->horizontalLine;
00238
00239 delete d->menuHandler;
00240
00241 d->menuHandler = NULL;
00242 delete d;
00243 }
00244
00245
00246 QString KStyle::defaultStyle()
00247 {
00248 if (QPixmap::defaultDepth() > 8)
00249 return QString("plastik");
00250 else
00251 return QString("light, 3rd revision");
00252 }
00253
00254
00255 void KStyle::polish( QWidget* widget )
00256 {
00257 if ( d->useFilledFrameWorkaround )
00258 {
00259 if ( QFrame *frame = ::qt_cast< QFrame* >( widget ) ) {
00260 QFrame::Shape shape = frame->frameShape();
00261 if (shape == QFrame::ToolBarPanel || shape == QFrame::MenuBarPanel)
00262 widget->installEventFilter(this);
00263 }
00264 }
00265 if (widget->isTopLevel())
00266 {
00267 if (!d->menuHandler && useDropShadow(widget))
00268 d->menuHandler = new TransparencyHandler(this, Disabled, 1.0, false);
00269
00270 if (d->menuHandler && useDropShadow(widget))
00271 widget->installEventFilter(d->menuHandler);
00272 }
00273 }
00274
00275
00276 void KStyle::unPolish( QWidget* widget )
00277 {
00278 if ( d->useFilledFrameWorkaround )
00279 {
00280 if ( QFrame *frame = ::qt_cast< QFrame* >( widget ) ) {
00281 QFrame::Shape shape = frame->frameShape();
00282 if (shape == QFrame::ToolBarPanel || shape == QFrame::MenuBarPanel)
00283 widget->removeEventFilter(this);
00284 }
00285 }
00286 if (widget->isTopLevel() && d->menuHandler && useDropShadow(widget))
00287 widget->removeEventFilter(d->menuHandler);
00288 }
00289
00290
00291
00292 void KStyle::polishPopupMenu( QPopupMenu* p )
00293 {
00294 if (!p->testWState( WState_Polished ))
00295 p->setCheckable(true);
00296
00297
00298 if ( d->menuHandler &&
00299 (strcmp(p->name(), "tear off menu") != 0))
00300 p->installEventFilter(d->menuHandler);
00301 }
00302
00303
00304
00305
00306
00307
00308 void KStyle::setScrollBarType(KStyleScrollBarType sbtype)
00309 {
00310 d->scrollbarType = sbtype;
00311 }
00312
00313 KStyle::KStyleFlags KStyle::styleFlags() const
00314 {
00315 return d->flags;
00316 }
00317
00318 void KStyle::renderMenuBlendPixmap( KPixmap &pix, const QColorGroup &cg,
00319 const QPopupMenu* ) const
00320 {
00321 pix.fill(cg.button());
00322 }
00323
00324
00325 void KStyle::drawKStylePrimitive( KStylePrimitive kpe,
00326 QPainter* p,
00327 const QWidget* widget,
00328 const QRect &r,
00329 const QColorGroup &cg,
00330 SFlags flags,
00331 const QStyleOption& ) const
00332 {
00333 switch( kpe )
00334 {
00335
00336
00337
00338 case KPE_DockWindowHandle: {
00339
00340
00341 QWidget* wid = const_cast<QWidget*>(widget);
00342 bool horizontal = flags & Style_Horizontal;
00343 int x,y,w,h,x2,y2;
00344
00345 r.rect( &x, &y, &w, &h );
00346 if ((w <= 2) || (h <= 2)) {
00347 p->fillRect(r, cg.highlight());
00348 return;
00349 }
00350
00351
00352 x2 = x + w - 1;
00353 y2 = y + h - 1;
00354
00355 QFont fnt;
00356 fnt = QApplication::font(wid);
00357 fnt.setPointSize( fnt.pointSize()-2 );
00358
00359
00360
00361
00362 QPixmap pix;
00363 if (horizontal)
00364 pix.resize( h-2, w-2 );
00365 else
00366 pix.resize( w-2, h-2 );
00367
00368 QString title = wid->parentWidget()->caption();
00369 QPainter p2;
00370 p2.begin(&pix);
00371 p2.fillRect(pix.rect(), cg.brush(QColorGroup::Highlight));
00372 p2.setPen(cg.highlightedText());
00373 p2.setFont(fnt);
00374 p2.drawText(pix.rect(), AlignCenter, title);
00375 p2.end();
00376
00377
00378 p->setPen(cg.dark());
00379 p->drawLine(x, y, x2, y);
00380 p->drawLine(x, y, x, y2);
00381 p->setPen(cg.light());
00382 p->drawLine(x+1, y2, x2, y2);
00383 p->drawLine(x2, y+1, x2, y2);
00384
00385 if (horizontal) {
00386 QWMatrix m;
00387 m.rotate(-90.0);
00388 QPixmap vpix = pix.xForm(m);
00389 bitBlt(wid, r.x()+1, r.y()+1, &vpix);
00390 } else
00391 bitBlt(wid, r.x()+1, r.y()+1, &pix);
00392
00393 break;
00394 }
00395
00396
00397
00398
00399
00400
00401
00402
00403 case KPE_ListViewExpander: {
00404
00405 int radius = (r.width() - 4) / 2;
00406 int centerx = r.x() + r.width()/2;
00407 int centery = r.y() + r.height()/2;
00408
00409
00410 p->setPen( cg.mid() );
00411 p->drawRect( r );
00412
00413
00414 p->setPen( cg.text() );
00415 p->drawLine( centerx - radius, centery, centerx + radius, centery );
00416 if ( flags & Style_On )
00417 p->drawLine( centerx, centery - radius, centerx, centery + radius );
00418 break;
00419 }
00420
00421 case KPE_ListViewBranch: {
00422
00423
00424
00425 if ( !d->verticalLine )
00426 {
00427
00428
00429 d->verticalLine = new QBitmap( 1, 129, true );
00430 d->horizontalLine = new QBitmap( 128, 1, true );
00431 QPointArray a( 64 );
00432 QPainter p2;
00433 p2.begin( d->verticalLine );
00434
00435 int i;
00436 for( i=0; i < 64; i++ )
00437 a.setPoint( i, 0, i*2+1 );
00438 p2.setPen( color1 );
00439 p2.drawPoints( a );
00440 p2.end();
00441 QApplication::flushX();
00442 d->verticalLine->setMask( *d->verticalLine );
00443
00444 p2.begin( d->horizontalLine );
00445 for( i=0; i < 64; i++ )
00446 a.setPoint( i, i*2+1, 0 );
00447 p2.setPen( color1 );
00448 p2.drawPoints( a );
00449 p2.end();
00450 QApplication::flushX();
00451 d->horizontalLine->setMask( *d->horizontalLine );
00452 }
00453
00454 p->setPen( cg.text() );
00455
00456 if (flags & Style_Horizontal)
00457 {
00458 int point = r.x();
00459 int other = r.y();
00460 int end = r.x()+r.width();
00461 int thickness = r.height();
00462
00463 while( point < end )
00464 {
00465 int i = 128;
00466 if ( i+point > end )
00467 i = end-point;
00468 p->drawPixmap( point, other, *d->horizontalLine, 0, 0, i, thickness );
00469 point += i;
00470 }
00471
00472 } else {
00473 int point = r.y();
00474 int other = r.x();
00475 int end = r.y()+r.height();
00476 int thickness = r.width();
00477 int pixmapoffset = (flags & Style_NoChange) ? 0 : 1;
00478
00479 while( point < end )
00480 {
00481 int i = 128;
00482 if ( i+point > end )
00483 i = end-point;
00484 p->drawPixmap( other, point, *d->verticalLine, 0, pixmapoffset, thickness, i );
00485 point += i;
00486 }
00487 }
00488
00489 break;
00490 }
00491
00492
00493
00494 case KPE_ToolBarHandle:
00495 case KPE_GeneralHandle:
00496 case KPE_SliderHandle:
00497 p->fillRect(r, cg.light());
00498 break;
00499
00500 case KPE_SliderGroove:
00501 p->fillRect(r, cg.dark());
00502 break;
00503
00504 default:
00505 p->fillRect(r, Qt::yellow);
00506 break;
00507 }
00508 }
00509
00510
00511 int KStyle::kPixelMetric( KStylePixelMetric kpm, const QWidget* ) const
00512 {
00513 int value;
00514 switch(kpm)
00515 {
00516 case KPM_ListViewBranchThickness:
00517 value = 1;
00518 break;
00519
00520 case KPM_MenuItemSeparatorHeight:
00521 case KPM_MenuItemHMargin:
00522 case KPM_MenuItemVMargin:
00523 case KPM_MenuItemHFrame:
00524 case KPM_MenuItemVFrame:
00525 case KPM_MenuItemCheckMarkHMargin:
00526 case KPM_MenuItemArrowHMargin:
00527 case KPM_MenuItemTabSpacing:
00528 default:
00529 value = 0;
00530 }
00531
00532 return value;
00533 }
00534
00535
00536
00537
00538 void KStyle::drawPrimitive( PrimitiveElement pe,
00539 QPainter* p,
00540 const QRect &r,
00541 const QColorGroup &cg,
00542 SFlags flags,
00543 const QStyleOption& opt ) const
00544 {
00545
00546
00547 if (pe == PE_DockWindowHandle)
00548 {
00549
00550 QWidget *widget, *parent;
00551
00552 if (p && p->device()->devType() == QInternal::Widget) {
00553 widget = static_cast<QWidget*>(p->device());
00554 parent = widget->parentWidget();
00555 } else
00556 return;
00557
00558
00559 if ( parent &&
00560 (parent->inherits("QToolBar") ||
00561 (parent->inherits("QMainWindow")) ))
00562
00563
00564 drawKStylePrimitive( KPE_ToolBarHandle, p, widget, r, cg, flags, opt );
00565
00566 else if ( widget->inherits("QDockWindowHandle") )
00567
00568
00569 drawKStylePrimitive( KPE_DockWindowHandle, p, widget, r, cg, flags, opt );
00570
00571 else
00572
00573 drawKStylePrimitive( KPE_GeneralHandle, p, widget, r, cg, flags, opt );
00574 #if QT_VERSION >= 0x030300
00575 #ifdef HAVE_XRENDER
00576 } else if ( d->semiTransparentRubberband && pe == QStyle::PE_RubberBand ) {
00577 QRect rect = r.normalize();
00578 QPoint point;
00579 point = p->xForm( point );
00580
00581 static XRenderColor clr = { 0, 0, 0, 0 };
00582 static unsigned long fillColor = 0;
00583 if ( fillColor != cg.highlight().rgb() ) {
00584 fillColor = cg.highlight().rgb();
00585
00586 unsigned long color = fillColor << 8 | 0x40;
00587
00588 int red = (color >> 24) & 0xff;
00589 int green = (color >> 16) & 0xff;
00590 int blue = (color >> 8) & 0xff;
00591 int alpha = (color >> 0) & 0xff;
00592
00593 red = red * alpha / 255;
00594 green = green * alpha / 255;
00595 blue = blue * alpha / 255;
00596
00597 clr.red = (red << 8) + red;
00598 clr.green = (green << 8) + green;
00599 clr.blue = (blue << 8) + blue;
00600 clr.alpha = (alpha << 8) + alpha;
00601 }
00602
00603 XRenderFillRectangle(
00604 p->device()->x11Display(),
00605 PictOpOver,
00606 p->device()->x11RenderHandle(),
00607 &clr,
00608 rect.x() + point.x(),
00609 rect.y() + point.y(),
00610 rect.width(),
00611 rect.height() );
00612
00613 p->save();
00614 p->setRasterOp( Qt::CopyROP );
00615 p->setPen( QPen( cg.highlight().dark( 160 ), 1 ) );
00616 p->setBrush( NoBrush );
00617 p->drawRect(
00618 rect.x() + point.x(),
00619 rect.y() + point.y(),
00620 rect.width(),
00621 rect.height() );
00622 p->restore();
00623 #endif
00624 #endif
00625 } else
00626 QCommonStyle::drawPrimitive( pe, p, r, cg, flags, opt );
00627 }
00628
00629
00630
00631 void KStyle::drawControl( ControlElement element,
00632 QPainter* p,
00633 const QWidget* widget,
00634 const QRect &r,
00635 const QColorGroup &cg,
00636 SFlags flags,
00637 const QStyleOption &opt ) const
00638 {
00639 switch (element)
00640 {
00641
00642
00643 case CE_TabBarTab: {
00644 const QTabBar* tb = (const QTabBar*) widget;
00645 QTabBar::Shape tbs = tb->shape();
00646 bool selected = flags & Style_Selected;
00647 int x = r.x(), y=r.y(), bottom=r.bottom(), right=r.right();
00648
00649 switch (tbs) {
00650
00651 case QTabBar::RoundedAbove: {
00652 if (!selected)
00653 p->translate(0,1);
00654 p->setPen(selected ? cg.light() : cg.shadow());
00655 p->drawLine(x, y+4, x, bottom);
00656 p->drawLine(x, y+4, x+4, y);
00657 p->drawLine(x+4, y, right-1, y);
00658 if (selected)
00659 p->setPen(cg.shadow());
00660 p->drawLine(right, y+1, right, bottom);
00661
00662 p->setPen(cg.midlight());
00663 p->drawLine(x+1, y+4, x+1, bottom);
00664 p->drawLine(x+1, y+4, x+4, y+1);
00665 p->drawLine(x+5, y+1, right-2, y+1);
00666
00667 if (selected) {
00668 p->setPen(cg.mid());
00669 p->drawLine(right-1, y+1, right-1, bottom);
00670 } else {
00671 p->setPen(cg.mid());
00672 p->drawPoint(right-1, y+1);
00673 p->drawLine(x+4, y+2, right-1, y+2);
00674 p->drawLine(x+3, y+3, right-1, y+3);
00675 p->fillRect(x+2, y+4, r.width()-3, r.height()-6, cg.mid());
00676
00677 p->setPen(cg.light());
00678 p->drawLine(x, bottom-1, right, bottom-1);
00679 p->translate(0,-1);
00680 }
00681 break;
00682 }
00683
00684 case QTabBar::RoundedBelow: {
00685 if (!selected)
00686 p->translate(0,-1);
00687 p->setPen(selected ? cg.light() : cg.shadow());
00688 p->drawLine(x, bottom-4, x, y);
00689 if (selected)
00690 p->setPen(cg.mid());
00691 p->drawLine(x, bottom-4, x+4, bottom);
00692 if (selected)
00693 p->setPen(cg.shadow());
00694 p->drawLine(x+4, bottom, right-1, bottom);
00695 p->drawLine(right, bottom-1, right, y);
00696
00697 p->setPen(cg.midlight());
00698 p->drawLine(x+1, bottom-4, x+1, y);
00699 p->drawLine(x+1, bottom-4, x+4, bottom-1);
00700 p->drawLine(x+5, bottom-1, right-2, bottom-1);
00701
00702 if (selected) {
00703 p->setPen(cg.mid());
00704 p->drawLine(right-1, y, right-1, bottom-1);
00705 } else {
00706 p->setPen(cg.mid());
00707 p->drawPoint(right-1, bottom-1);
00708 p->drawLine(x+4, bottom-2, right-1, bottom-2);
00709 p->drawLine(x+3, bottom-3, right-1, bottom-3);
00710 p->fillRect(x+2, y+2, r.width()-3, r.height()-6, cg.mid());
00711 p->translate(0,1);
00712 p->setPen(cg.dark());
00713 p->drawLine(x, y, right, y);
00714 }
00715 break;
00716 }
00717
00718 case QTabBar::TriangularAbove: {
00719 if (!selected)
00720 p->translate(0,1);
00721 p->setPen(selected ? cg.light() : cg.shadow());
00722 p->drawLine(x, bottom, x, y+6);
00723 p->drawLine(x, y+6, x+6, y);
00724 p->drawLine(x+6, y, right-6, y);
00725 if (selected)
00726 p->setPen(cg.mid());
00727 p->drawLine(right-5, y+1, right-1, y+5);
00728 p->setPen(cg.shadow());
00729 p->drawLine(right, y+6, right, bottom);
00730
00731 p->setPen(cg.midlight());
00732 p->drawLine(x+1, bottom, x+1, y+6);
00733 p->drawLine(x+1, y+6, x+6, y+1);
00734 p->drawLine(x+6, y+1, right-6, y+1);
00735 p->drawLine(right-5, y+2, right-2, y+5);
00736 p->setPen(cg.mid());
00737 p->drawLine(right-1, y+6, right-1, bottom);
00738
00739 QPointArray a(6);
00740 a.setPoint(0, x+2, bottom);
00741 a.setPoint(1, x+2, y+7);
00742 a.setPoint(2, x+7, y+2);
00743 a.setPoint(3, right-7, y+2);
00744 a.setPoint(4, right-2, y+7);
00745 a.setPoint(5, right-2, bottom);
00746 p->setPen (selected ? cg.background() : cg.mid());
00747 p->setBrush(selected ? cg.background() : cg.mid());
00748 p->drawPolygon(a);
00749 p->setBrush(NoBrush);
00750 if (!selected) {
00751 p->translate(0,-1);
00752 p->setPen(cg.light());
00753 p->drawLine(x, bottom, right, bottom);
00754 }
00755 break;
00756 }
00757
00758 default: {
00759 if (!selected)
00760 p->translate(0,-1);
00761 p->setPen(selected ? cg.light() : cg.shadow());
00762 p->drawLine(x, y, x, bottom-6);
00763 if (selected)
00764 p->setPen(cg.mid());
00765 p->drawLine(x, bottom-6, x+6, bottom);
00766 if (selected)
00767 p->setPen(cg.shadow());
00768 p->drawLine(x+6, bottom, right-6, bottom);
00769 p->drawLine(right-5, bottom-1, right-1, bottom-5);
00770 if (!selected)
00771 p->setPen(cg.shadow());
00772 p->drawLine(right, bottom-6, right, y);
00773
00774 p->setPen(cg.midlight());
00775 p->drawLine(x+1, y, x+1, bottom-6);
00776 p->drawLine(x+1, bottom-6, x+6, bottom-1);
00777 p->drawLine(x+6, bottom-1, right-6, bottom-1);
00778 p->drawLine(right-5, bottom-2, right-2, bottom-5);
00779 p->setPen(cg.mid());
00780 p->drawLine(right-1, bottom-6, right-1, y);
00781
00782 QPointArray a(6);
00783 a.setPoint(0, x+2, y);
00784 a.setPoint(1, x+2, bottom-7);
00785 a.setPoint(2, x+7, bottom-2);
00786 a.setPoint(3, right-7, bottom-2);
00787 a.setPoint(4, right-2, bottom-7);
00788 a.setPoint(5, right-2, y);
00789 p->setPen (selected ? cg.background() : cg.mid());
00790 p->setBrush(selected ? cg.background() : cg.mid());
00791 p->drawPolygon(a);
00792 p->setBrush(NoBrush);
00793 if (!selected) {
00794 p->translate(0,1);
00795 p->setPen(cg.dark());
00796 p->drawLine(x, y, right, y);
00797 }
00798 break;
00799 }
00800 };
00801
00802 break;
00803 }
00804
00805
00806
00807 case CE_PopupMenuScroller: {
00808 p->fillRect(r, cg.background());
00809 drawPrimitive(PE_ButtonTool, p, r, cg, Style_Enabled);
00810 drawPrimitive((flags & Style_Up) ? PE_ArrowUp : PE_ArrowDown, p, r, cg, Style_Enabled);
00811 break;
00812 }
00813
00814
00815
00816
00817 case CE_ProgressBarGroove: {
00818 QRect fr = subRect(SR_ProgressBarGroove, widget);
00819 drawPrimitive(PE_Panel, p, fr, cg, Style_Sunken, QStyleOption::Default);
00820 break;
00821 }
00822
00823 case CE_ProgressBarContents: {
00824
00825 const QProgressBar* pb = (const QProgressBar*)widget;
00826 QRect cr = subRect(SR_ProgressBarContents, widget);
00827 double progress = pb->progress();
00828 bool reverse = QApplication::reverseLayout();
00829 int steps = pb->totalSteps();
00830
00831 if (!cr.isValid())
00832 return;
00833
00834
00835 if (progress > 0 || steps == 0) {
00836 double pg = (steps == 0) ? 0.1 : progress / steps;
00837 int width = QMIN(cr.width(), (int)(pg * cr.width()));
00838 if (steps == 0) {
00839
00840 if (width < 1) width = 1;
00841
00842 int remWidth = cr.width() - width;
00843 if (remWidth <= 0) remWidth = 1;
00844
00845 int pstep = int(progress) % ( 2 * remWidth );
00846
00847 if ( pstep > remWidth ) {
00848
00849
00850 pstep = - (pstep - 2 * remWidth );
00851 }
00852
00853 if (reverse)
00854 p->fillRect(cr.x() + cr.width() - width - pstep, cr.y(), width, cr.height(),
00855 cg.brush(QColorGroup::Highlight));
00856 else
00857 p->fillRect(cr.x() + pstep, cr.y(), width, cr.height(),
00858 cg.brush(QColorGroup::Highlight));
00859
00860 return;
00861 }
00862
00863
00864
00865 if (d->highcolor) {
00866 QColor c(cg.highlight());
00867 KPixmap pix;
00868 pix.resize(cr.width(), cr.height());
00869 KPixmapEffect::gradient(pix, reverse ? c.light(150) : c.dark(150),
00870 reverse ? c.dark(150) : c.light(150),
00871 KPixmapEffect::HorizontalGradient);
00872 if (reverse)
00873 p->drawPixmap(cr.x()+(cr.width()-width), cr.y(), pix,
00874 cr.width()-width, 0, width, cr.height());
00875 else
00876 p->drawPixmap(cr.x(), cr.y(), pix, 0, 0, width, cr.height());
00877 } else
00878 if (reverse)
00879 p->fillRect(cr.x()+(cr.width()-width), cr.y(), width, cr.height(),
00880 cg.brush(QColorGroup::Highlight));
00881 else
00882 p->fillRect(cr.x(), cr.y(), width, cr.height(),
00883 cg.brush(QColorGroup::Highlight));
00884 }
00885 break;
00886 }
00887
00888 case CE_ProgressBarLabel: {
00889 const QProgressBar* pb = (const QProgressBar*)widget;
00890 QRect cr = subRect(SR_ProgressBarContents, widget);
00891 double progress = pb->progress();
00892 bool reverse = QApplication::reverseLayout();
00893 int steps = pb->totalSteps();
00894
00895 if (!cr.isValid())
00896 return;
00897
00898 QFont font = p->font();
00899 font.setBold(true);
00900 p->setFont(font);
00901
00902
00903 if (progress > 0 || steps == 0) {
00904 double pg = (steps == 0) ? 1.0 : progress / steps;
00905 int width = QMIN(cr.width(), (int)(pg * cr.width()));
00906 QRect crect;
00907 if (reverse)
00908 crect.setRect(cr.x()+(cr.width()-width), cr.y(), cr.width(), cr.height());
00909 else
00910 crect.setRect(cr.x()+width, cr.y(), cr.width(), cr.height());
00911
00912 p->save();
00913 p->setPen(pb->isEnabled() ? (reverse ? cg.text() : cg.highlightedText()) : cg.text());
00914 p->drawText(r, AlignCenter, pb->progressString());
00915 p->setClipRect(crect);
00916 p->setPen(reverse ? cg.highlightedText() : cg.text());
00917 p->drawText(r, AlignCenter, pb->progressString());
00918 p->restore();
00919
00920 } else {
00921 p->setPen(cg.text());
00922 p->drawText(r, AlignCenter, pb->progressString());
00923 }
00924
00925 break;
00926 }
00927
00928 default:
00929 QCommonStyle::drawControl(element, p, widget, r, cg, flags, opt);
00930 }
00931 }
00932
00933
00934 QRect KStyle::subRect(SubRect r, const QWidget* widget) const
00935 {
00936 switch(r)
00937 {
00938
00939
00940 case SR_ProgressBarGroove:
00941 return widget->rect();
00942
00943 case SR_ProgressBarContents:
00944 case SR_ProgressBarLabel: {
00945
00946 QRect rt = widget->rect();
00947 return QRect(rt.x()+2, rt.y()+2, rt.width()-4, rt.height()-4);
00948 }
00949
00950 default:
00951 return QCommonStyle::subRect(r, widget);
00952 }
00953 }
00954
00955
00956 int KStyle::pixelMetric(PixelMetric m, const QWidget* widget) const
00957 {
00958 switch(m)
00959 {
00960
00961
00962 case PM_ButtonShiftHorizontal:
00963 case PM_ButtonShiftVertical:
00964 return 1;
00965
00966 case PM_DockWindowHandleExtent:
00967 {
00968 QWidget* parent = 0;
00969
00970
00971 if (widget && (parent = widget->parentWidget() )
00972 && !parent->inherits("QToolBar")
00973 && !parent->inherits("QMainWindow")
00974 && widget->inherits("QDockWindowHandle") )
00975 return widget->fontMetrics().lineSpacing();
00976 else
00977 return QCommonStyle::pixelMetric(m, widget);
00978 }
00979
00980
00981
00982 case PM_TabBarTabHSpace:
00983 return 24;
00984
00985 case PM_TabBarTabVSpace: {
00986 const QTabBar * tb = (const QTabBar *) widget;
00987 if ( tb->shape() == QTabBar::RoundedAbove ||
00988 tb->shape() == QTabBar::RoundedBelow )
00989 return 10;
00990 else
00991 return 4;
00992 }
00993
00994 case PM_TabBarTabOverlap: {
00995 const QTabBar* tb = (const QTabBar*)widget;
00996 QTabBar::Shape tbs = tb->shape();
00997
00998 if ( (tbs == QTabBar::RoundedAbove) ||
00999 (tbs == QTabBar::RoundedBelow) )
01000 return 0;
01001 else
01002 return 2;
01003 }
01004
01005
01006
01007 case PM_SliderLength:
01008 return 18;
01009
01010 case PM_SliderThickness:
01011 return 24;
01012
01013
01014
01015 case PM_SliderControlThickness: {
01016 const QSlider* slider = (const QSlider*)widget;
01017 QSlider::TickSetting ts = slider->tickmarks();
01018 int thickness = (slider->orientation() == Horizontal) ?
01019 slider->height() : slider->width();
01020 switch (ts) {
01021 case QSlider::NoMarks:
01022 break;
01023 case QSlider::Both:
01024 thickness = (thickness/2) + 3;
01025 break;
01026 default:
01027 thickness = ((thickness*2)/3) + 3;
01028 break;
01029 };
01030 return thickness;
01031 }
01032
01033
01034
01035 case PM_SplitterWidth:
01036 if (widget && widget->inherits("QDockWindowResizeHandle"))
01037 return 8;
01038 else
01039 return 6;
01040
01041
01042
01043 case PM_MenuBarFrameWidth:
01044 return 1;
01045
01046 case PM_DockWindowFrameWidth:
01047 return 1;
01048
01049
01050
01051 case PM_MaximumDragDistance:
01052 return -1;
01053
01054 case PM_MenuBarItemSpacing:
01055 return 5;
01056
01057 case PM_ToolBarItemSpacing:
01058 return 0;
01059
01060 case PM_PopupMenuScrollerHeight:
01061 return pixelMetric( PM_ScrollBarExtent, 0);
01062
01063 default:
01064 return QCommonStyle::pixelMetric( m, widget );
01065 }
01066 }
01067
01068
01069 static QListViewItem* nextVisibleSibling(QListViewItem* item)
01070 {
01071 QListViewItem* sibling = item;
01072 do
01073 {
01074 sibling = sibling->nextSibling();
01075 }
01076 while (sibling && !sibling->isVisible());
01077
01078 return sibling;
01079 }
01080
01081 void KStyle::drawComplexControl( ComplexControl control,
01082 QPainter* p,
01083 const QWidget* widget,
01084 const QRect &r,
01085 const QColorGroup &cg,
01086 SFlags flags,
01087 SCFlags controls,
01088 SCFlags active,
01089 const QStyleOption &opt ) const
01090 {
01091 switch(control)
01092 {
01093
01094
01095 case CC_ScrollBar: {
01096
01097 bool useThreeButtonScrollBar = (d->scrollbarType & ThreeButtonScrollBar);
01098
01099 const QScrollBar *sb = (const QScrollBar*)widget;
01100 bool maxedOut = (sb->minValue() == sb->maxValue());
01101 bool horizontal = (sb->orientation() == Qt::Horizontal);
01102 SFlags sflags = ((horizontal ? Style_Horizontal : Style_Default) |
01103 (maxedOut ? Style_Default : Style_Enabled));
01104
01105 QRect addline, subline, subline2, addpage, subpage, slider, first, last;
01106 subline = querySubControlMetrics(control, widget, SC_ScrollBarSubLine, opt);
01107 addline = querySubControlMetrics(control, widget, SC_ScrollBarAddLine, opt);
01108 subpage = querySubControlMetrics(control, widget, SC_ScrollBarSubPage, opt);
01109 addpage = querySubControlMetrics(control, widget, SC_ScrollBarAddPage, opt);
01110 slider = querySubControlMetrics(control, widget, SC_ScrollBarSlider, opt);
01111 first = querySubControlMetrics(control, widget, SC_ScrollBarFirst, opt);
01112 last = querySubControlMetrics(control, widget, SC_ScrollBarLast, opt);
01113 subline2 = addline;
01114
01115 if ( useThreeButtonScrollBar )
01116 if (horizontal)
01117 subline2.moveBy(-addline.width(), 0);
01118 else
01119 subline2.moveBy(0, -addline.height());
01120
01121
01122 if ((controls & SC_ScrollBarSubLine) && subline.isValid()) {
01123 drawPrimitive(PE_ScrollBarSubLine, p, subline, cg,
01124 sflags | (active == SC_ScrollBarSubLine ?
01125 Style_Down : Style_Default));
01126
01127 if (useThreeButtonScrollBar && subline2.isValid())
01128 drawPrimitive(PE_ScrollBarSubLine, p, subline2, cg,
01129 sflags | (active == SC_ScrollBarSubLine ?
01130 Style_Down : Style_Default));
01131 }
01132
01133 if ((controls & SC_ScrollBarAddLine) && addline.isValid())
01134 drawPrimitive(PE_ScrollBarAddLine, p, addline, cg,
01135 sflags | ((active == SC_ScrollBarAddLine) ?
01136 Style_Down : Style_Default));
01137
01138 if ((controls & SC_ScrollBarSubPage) && subpage.isValid())
01139 drawPrimitive(PE_ScrollBarSubPage, p, subpage, cg,
01140 sflags | ((active == SC_ScrollBarSubPage) ?
01141 Style_Down : Style_Default));
01142
01143 if ((controls & SC_ScrollBarAddPage) && addpage.isValid())
01144 drawPrimitive(PE_ScrollBarAddPage, p, addpage, cg,
01145 sflags | ((active == SC_ScrollBarAddPage) ?
01146 Style_Down : Style_Default));
01147
01148 if ((controls & SC_ScrollBarFirst) && first.isValid())
01149 drawPrimitive(PE_ScrollBarFirst, p, first, cg,
01150 sflags | ((active == SC_ScrollBarFirst) ?
01151 Style_Down : Style_Default));
01152
01153 if ((controls & SC_ScrollBarLast) && last.isValid())
01154 drawPrimitive(PE_ScrollBarLast, p, last, cg,
01155 sflags | ((active == SC_ScrollBarLast) ?
01156 Style_Down : Style_Default));
01157
01158 if ((controls & SC_ScrollBarSlider) && slider.isValid()) {
01159 drawPrimitive(PE_ScrollBarSlider, p, slider, cg,
01160 sflags | ((active == SC_ScrollBarSlider) ?
01161 Style_Down : Style_Default));
01162
01163 if (sb->hasFocus()) {
01164 QRect fr(slider.x() + 2, slider.y() + 2,
01165 slider.width() - 5, slider.height() - 5);
01166 drawPrimitive(PE_FocusRect, p, fr, cg, Style_Default);
01167 }
01168 }
01169 break;
01170 }
01171
01172
01173
01174
01175 case CC_Slider: {
01176 const QSlider* slider = (const QSlider*)widget;
01177 QRect groove = querySubControlMetrics(CC_Slider, widget, SC_SliderGroove, opt);
01178 QRect handle = querySubControlMetrics(CC_Slider, widget, SC_SliderHandle, opt);
01179
01180
01181 QPixmap pix(widget->size());
01182 QPainter p2;
01183 p2.begin(&pix);
01184
01185 if ( slider->parentWidget() &&
01186 slider->parentWidget()->backgroundPixmap() &&
01187 !slider->parentWidget()->backgroundPixmap()->isNull() ) {
01188 QPixmap pixmap = *(slider->parentWidget()->backgroundPixmap());
01189 p2.drawTiledPixmap(r, pixmap, slider->pos());
01190 } else
01191 pix.fill(cg.background());
01192
01193
01194 if ((controls & SC_SliderGroove) && groove.isValid()) {
01195 drawKStylePrimitive( KPE_SliderGroove, &p2, widget, groove, cg, flags, opt );
01196
01197
01198 if (slider->hasFocus())
01199 drawPrimitive(PE_FocusRect, &p2, groove, cg);
01200 }
01201
01202
01203 if (controls & SC_SliderTickmarks)
01204 QCommonStyle::drawComplexControl(control, &p2, widget,
01205 r, cg, flags, SC_SliderTickmarks, active, opt);
01206
01207
01208 if ((controls & SC_SliderHandle) && handle.isValid()) {
01209 if (active == SC_SliderHandle)
01210 flags |= Style_Active;
01211 drawKStylePrimitive( KPE_SliderHandle, &p2, widget, handle, cg, flags, opt );
01212 }
01213
01214 p2.end();
01215 bitBlt((QWidget*)widget, r.x(), r.y(), &pix);
01216 break;
01217 }
01218
01219
01220
01221 case CC_ListView: {
01222
01223
01224
01225
01226
01227
01228
01229 if ( controls & SC_ListView )
01230 QCommonStyle::drawComplexControl( control, p, widget, r, cg, flags, controls, active, opt );
01231
01232
01233 if ( controls & (SC_ListViewBranch | SC_ListViewExpand) )
01234 {
01235
01236 if (opt.isDefault())
01237 break;
01238
01239 QListViewItem *item = opt.listViewItem();
01240 QListViewItem *child = item->firstChild();
01241
01242 int y = r.y();
01243 int c;
01244 int dotoffset = 0;
01245 QPointArray dotlines;
01246
01247 if ( active == SC_All && controls == SC_ListViewExpand ) {
01248
01249 c = 2;
01250 dotlines.resize(2);
01251 dotlines[0] = QPoint( r.right(), r.top() );
01252 dotlines[1] = QPoint( r.right(), r.bottom() );
01253
01254 } else {
01255
01256 int linetop = 0, linebot = 0;
01257
01258 dotoffset = (item->itemPos() + item->height() - y) % 2;
01259 dotlines.resize( item->childCount() * 4 );
01260 c = 0;
01261
01262
01263 while ( child && y + child->height() <= 0 )
01264 {
01265 y += child->totalHeight();
01266 child = nextVisibleSibling(child);
01267 }
01268
01269 int bx = r.width() / 2;
01270
01271
01272 QListView* v = item->listView();
01273 int lh = QMAX( p->fontMetrics().height() + 2 * v->itemMargin(),
01274 QApplication::globalStrut().height() );
01275 if ( lh % 2 > 0 )
01276 lh++;
01277
01278
01279 QRect boxrect;
01280 QStyle::StyleFlags boxflags;
01281 while ( child && y < r.height() )
01282 {
01283 linebot = y + lh/2;
01284 if ( (child->isExpandable() || child->childCount()) &&
01285 (child->height() > 0) )
01286 {
01287
01288 boxrect = QRect( bx-4, linebot-4, 9, 9 );
01289 boxflags = child->isOpen() ? QStyle::Style_Off : QStyle::Style_On;
01290
01291
01292 drawKStylePrimitive( KPE_ListViewExpander, p, NULL, boxrect, cg, boxflags, opt );
01293
01294
01295 p->setPen( cg.mid() );
01296 dotlines[c++] = QPoint( bx, linetop );
01297 dotlines[c++] = QPoint( bx, linebot - 5 );
01298 dotlines[c++] = QPoint( bx + 5, linebot );
01299 dotlines[c++] = QPoint( r.width(), linebot );
01300 linetop = linebot + 5;
01301 } else {
01302
01303 dotlines[c++] = QPoint( bx+1, linebot );
01304 dotlines[c++] = QPoint( r.width(), linebot );
01305 }
01306
01307 y += child->totalHeight();
01308 child = nextVisibleSibling(child);
01309 }
01310
01311 if ( child )
01312 linebot = r.height();
01313
01314 if ( linetop < linebot )
01315 {
01316 dotlines[c++] = QPoint( bx, linetop );
01317 dotlines[c++] = QPoint( bx, linebot );
01318 }
01319 }
01320
01321
01322 static int thickness = kPixelMetric( KPM_ListViewBranchThickness );
01323 int line;
01324 QRect branchrect;
01325 QStyle::StyleFlags branchflags;
01326 for( line = 0; line < c; line += 2 )
01327 {
01328
01329
01330
01331
01332
01333
01334
01335 if ( dotlines[line].y() == dotlines[line+1].y() )
01336 {
01337
01338 int end = dotlines[line+1].x();
01339 int point = dotlines[line].x();
01340 int other = dotlines[line].y();
01341
01342 branchrect = QRect( point, other-(thickness/2), end-point, thickness );
01343 branchflags = QStyle::Style_Horizontal;
01344
01345
01346 drawKStylePrimitive( KPE_ListViewBranch, p, NULL, branchrect, cg, branchflags, opt );
01347
01348 } else {
01349
01350 int end = dotlines[line+1].y();
01351 int point = dotlines[line].y();
01352 int other = dotlines[line].x();
01353 int pixmapoffset = ((point & 1) != dotoffset ) ? 1 : 0;
01354
01355 branchrect = QRect( other-(thickness/2), point, thickness, end-point );
01356 if (!pixmapoffset)
01357 branchflags = QStyle::Style_NoChange;
01358 else
01359 branchflags = QStyle::Style_Default;
01360
01361
01362 drawKStylePrimitive( KPE_ListViewBranch, p, NULL, branchrect, cg, branchflags, opt );
01363 }
01364 }
01365 }
01366 break;
01367 }
01368
01369 default:
01370 QCommonStyle::drawComplexControl( control, p, widget, r, cg,
01371 flags, controls, active, opt );
01372 break;
01373 }
01374 }
01375
01376
01377 QStyle::SubControl KStyle::querySubControl( ComplexControl control,
01378 const QWidget* widget,
01379 const QPoint &pos,
01380 const QStyleOption &opt ) const
01381 {
01382 QStyle::SubControl ret = QCommonStyle::querySubControl(control, widget, pos, opt);
01383
01384 if (d->scrollbarType == ThreeButtonScrollBar) {
01385
01386 if (control == CC_ScrollBar && ret == SC_None)
01387 ret = SC_ScrollBarSubLine;
01388 }
01389 return ret;
01390 }
01391
01392
01393 QRect KStyle::querySubControlMetrics( ComplexControl control,
01394 const QWidget* widget,
01395 SubControl sc,
01396 const QStyleOption &opt ) const
01397 {
01398 QRect ret;
01399
01400 if (control == CC_ScrollBar)
01401 {
01402 bool threeButtonScrollBar = d->scrollbarType & ThreeButtonScrollBar;
01403 bool platinumScrollBar = d->scrollbarType & PlatinumStyleScrollBar;
01404 bool nextScrollBar = d->scrollbarType & NextStyleScrollBar;
01405
01406 const QScrollBar *sb = (const QScrollBar*)widget;
01407 bool horizontal = sb->orientation() == Qt::Horizontal;
01408 int sliderstart = sb->sliderStart();
01409 int sbextent = pixelMetric(PM_ScrollBarExtent, widget);
01410 int maxlen = (horizontal ? sb->width() : sb->height())
01411 - (sbextent * (threeButtonScrollBar ? 3 : 2));
01412 int sliderlen;
01413
01414
01415 if (sb->maxValue() != sb->minValue())
01416 {
01417 uint range = sb->maxValue() - sb->minValue();
01418 sliderlen = (sb->pageStep() * maxlen) / (range + sb->pageStep());
01419
01420 int slidermin = pixelMetric( PM_ScrollBarSliderMin, widget );
01421 if ( sliderlen < slidermin || range > INT_MAX / 2 )
01422 sliderlen = slidermin;
01423 if ( sliderlen > maxlen )
01424 sliderlen = maxlen;
01425 } else
01426 sliderlen = maxlen;
01427
01428
01429 switch (sc)
01430 {
01431 case SC_ScrollBarSubLine: {
01432
01433 if (platinumScrollBar) {
01434 if (horizontal)
01435 ret.setRect(sb->width() - 2 * sbextent, 0, sbextent, sbextent);
01436 else
01437 ret.setRect(0, sb->height() - 2 * sbextent, sbextent, sbextent);
01438 } else
01439 ret.setRect(0, 0, sbextent, sbextent);
01440 break;
01441 }
01442
01443 case SC_ScrollBarAddLine: {
01444
01445 if (nextScrollBar) {
01446 if (horizontal)
01447 ret.setRect(sbextent, 0, sbextent, sbextent);
01448 else
01449 ret.setRect(0, sbextent, sbextent, sbextent);
01450 } else {
01451 if (horizontal)
01452 ret.setRect(sb->width() - sbextent, 0, sbextent, sbextent);
01453 else
01454 ret.setRect(0, sb->height() - sbextent, sbextent, sbextent);
01455 }
01456 break;
01457 }
01458
01459 case SC_ScrollBarSubPage: {
01460
01461 if (platinumScrollBar) {
01462 if (horizontal)
01463 ret.setRect(0, 0, sliderstart, sbextent);
01464 else
01465 ret.setRect(0, 0, sbextent, sliderstart);
01466 } else if (nextScrollBar) {
01467 if (horizontal)
01468 ret.setRect(sbextent*2, 0, sliderstart-2*sbextent, sbextent);
01469 else
01470 ret.setRect(0, sbextent*2, sbextent, sliderstart-2*sbextent);
01471 } else {
01472 if (horizontal)
01473 ret.setRect(sbextent, 0, sliderstart - sbextent, sbextent);
01474 else
01475 ret.setRect(0, sbextent, sbextent, sliderstart - sbextent);
01476 }
01477 break;
01478 }
01479
01480 case SC_ScrollBarAddPage: {
01481
01482 int fudge;
01483
01484 if (platinumScrollBar)
01485 fudge = 0;
01486 else if (nextScrollBar)
01487 fudge = 2*sbextent;
01488 else
01489 fudge = sbextent;
01490
01491 if (horizontal)
01492 ret.setRect(sliderstart + sliderlen, 0,
01493 maxlen - sliderstart - sliderlen + fudge, sbextent);
01494 else
01495 ret.setRect(0, sliderstart + sliderlen, sbextent,
01496 maxlen - sliderstart - sliderlen + fudge);
01497 break;
01498 }
01499
01500 case SC_ScrollBarGroove: {
01501 int multi = threeButtonScrollBar ? 3 : 2;
01502 int fudge;
01503
01504 if (platinumScrollBar)
01505 fudge = 0;
01506 else if (nextScrollBar)
01507 fudge = 2*sbextent;
01508 else
01509 fudge = sbextent;
01510
01511 if (horizontal)
01512 ret.setRect(fudge, 0, sb->width() - sbextent * multi, sb->height());
01513 else
01514 ret.setRect(0, fudge, sb->width(), sb->height() - sbextent * multi);
01515 break;
01516 }
01517
01518 case SC_ScrollBarSlider: {
01519 if (horizontal)
01520 ret.setRect(sliderstart, 0, sliderlen, sbextent);
01521 else
01522 ret.setRect(0, sliderstart, sbextent, sliderlen);
01523 break;
01524 }
01525
01526 default:
01527 ret = QCommonStyle::querySubControlMetrics(control, widget, sc, opt);
01528 break;
01529 }
01530 } else
01531 ret = QCommonStyle::querySubControlMetrics(control, widget, sc, opt);
01532
01533 return ret;
01534 }
01535
01536 static const char * const kstyle_close_xpm[] = {
01537 "12 12 2 1",
01538 "# c #000000",
01539 ". c None",
01540 "............",
01541 "............",
01542 "..##....##..",
01543 "...##..##...",
01544 "....####....",
01545 ".....##.....",
01546 "....####....",
01547 "...##..##...",
01548 "..##....##..",
01549 "............",
01550 "............",
01551 "............"};
01552
01553 static const char * const kstyle_maximize_xpm[]={
01554 "12 12 2 1",
01555 "# c #000000",
01556 ". c None",
01557 "............",
01558 "............",
01559 ".##########.",
01560 ".##########.",
01561 ".#........#.",
01562 ".#........#.",
01563 ".#........#.",
01564 ".#........#.",
01565 ".#........#.",
01566 ".#........#.",
01567 ".##########.",
01568 "............"};
01569
01570
01571 static const char * const kstyle_minimize_xpm[] = {
01572 "12 12 2 1",
01573 "# c #000000",
01574 ". c None",
01575 "............",
01576 "............",
01577 "............",
01578 "............",
01579 "............",
01580 "............",
01581 "............",
01582 "...######...",
01583 "...######...",
01584 "............",
01585 "............",
01586 "............"};
01587
01588 static const char * const kstyle_normalizeup_xpm[] = {
01589 "12 12 2 1",
01590 "# c #000000",
01591 ". c None",
01592 "............",
01593 "...#######..",
01594 "...#######..",
01595 "...#.....#..",
01596 ".#######.#..",
01597 ".#######.#..",
01598 ".#.....#.#..",
01599 ".#.....###..",
01600 ".#.....#....",
01601 ".#.....#....",
01602 ".#######....",
01603 "............"};
01604
01605
01606 static const char * const kstyle_shade_xpm[] = {
01607 "12 12 2 1",
01608 "# c #000000",
01609 ". c None",
01610 "............",
01611 "............",
01612 "............",
01613 "............",
01614 "............",
01615 ".....#......",
01616 "....###.....",
01617 "...#####....",
01618 "..#######...",
01619 "............",
01620 "............",
01621 "............"};
01622
01623 static const char * const kstyle_unshade_xpm[] = {
01624 "12 12 2 1",
01625 "# c #000000",
01626 ". c None",
01627 "............",
01628 "............",
01629 "............",
01630 "............",
01631 "..#######...",
01632 "...#####....",
01633 "....###.....",
01634 ".....#......",
01635 "............",
01636 "............",
01637 "............",
01638 "............"};
01639
01640 static const char * const dock_window_close_xpm[] = {
01641 "8 8 2 1",
01642 "# c #000000",
01643 ". c None",
01644 "##....##",
01645 ".##..##.",
01646 "..####..",
01647 "...##...",
01648 "..####..",
01649 ".##..##.",
01650 "##....##",
01651 "........"};
01652
01653
01654
01655
01656
01657
01658
01659
01660 static const char * const information_xpm[]={
01661 "32 32 5 1",
01662 ". c None",
01663 "c c #000000",
01664 "* c #999999",
01665 "a c #ffffff",
01666 "b c #0000ff",
01667 "...........********.............",
01668 "........***aaaaaaaa***..........",
01669 "......**aaaaaaaaaaaaaa**........",
01670 ".....*aaaaaaaaaaaaaaaaaa*.......",
01671 "....*aaaaaaaabbbbaaaaaaaac......",
01672 "...*aaaaaaaabbbbbbaaaaaaaac.....",
01673 "..*aaaaaaaaabbbbbbaaaaaaaaac....",
01674 ".*aaaaaaaaaaabbbbaaaaaaaaaaac...",
01675 ".*aaaaaaaaaaaaaaaaaaaaaaaaaac*..",
01676 "*aaaaaaaaaaaaaaaaaaaaaaaaaaaac*.",
01677 "*aaaaaaaaaabbbbbbbaaaaaaaaaaac*.",
01678 "*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
01679 "*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
01680 "*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
01681 "*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
01682 "*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
01683 ".*aaaaaaaaaaabbbbbaaaaaaaaaac***",
01684 ".*aaaaaaaaaaabbbbbaaaaaaaaaac***",
01685 "..*aaaaaaaaaabbbbbaaaaaaaaac***.",
01686 "...caaaaaaabbbbbbbbbaaaaaac****.",
01687 "....caaaaaaaaaaaaaaaaaaaac****..",
01688 ".....caaaaaaaaaaaaaaaaaac****...",
01689 "......ccaaaaaaaaaaaaaacc****....",
01690 ".......*cccaaaaaaaaccc*****.....",
01691 "........***cccaaaac*******......",
01692 "..........****caaac*****........",
01693 ".............*caaac**...........",
01694 "...............caac**...........",
01695 "................cac**...........",
01696 ".................cc**...........",
01697 "..................***...........",
01698 "...................**..........."};
01699
01700 static const char* const warning_xpm[]={
01701 "32 32 4 1",
01702 ". c None",
01703 "a c #ffff00",
01704 "* c #000000",
01705 "b c #999999",
01706 ".............***................",
01707 "............*aaa*...............",
01708 "...........*aaaaa*b.............",
01709 "...........*aaaaa*bb............",
01710 "..........*aaaaaaa*bb...........",
01711 "..........*aaaaaaa*bb...........",
01712 ".........*aaaaaaaaa*bb..........",
01713 ".........*aaaaaaaaa*bb..........",
01714 "........*aaaaaaaaaaa*bb.........",
01715 "........*aaaa***aaaa*bb.........",
01716 ".......*aaaa*****aaaa*bb........",
01717 ".......*aaaa*****aaaa*bb........",
01718 "......*aaaaa*****aaaaa*bb.......",
01719 "......*aaaaa*****aaaaa*bb.......",
01720 ".....*aaaaaa*****aaaaaa*bb......",
01721 ".....*aaaaaa*****aaaaaa*bb......",
01722 "....*aaaaaaaa***aaaaaaaa*bb.....",
01723 "....*aaaaaaaa***aaaaaaaa*bb.....",
01724 "...*aaaaaaaaa***aaaaaaaaa*bb....",
01725 "...*aaaaaaaaaa*aaaaaaaaaa*bb....",
01726 "..*aaaaaaaaaaa*aaaaaaaaaaa*bb...",
01727 "..*aaaaaaaaaaaaaaaaaaaaaaa*bb...",
01728 ".*aaaaaaaaaaaa**aaaaaaaaaaa*bb..",
01729 ".*aaaaaaaaaaa****aaaaaaaaaa*bb..",
01730 "*aaaaaaaaaaaa****aaaaaaaaaaa*bb.",
01731 "*aaaaaaaaaaaaa**aaaaaaaaaaaa*bb.",
01732 "*aaaaaaaaaaaaaaaaaaaaaaaaaaa*bbb",
01733 "*aaaaaaaaaaaaaaaaaaaaaaaaaaa*bbb",
01734 ".*aaaaaaaaaaaaaaaaaaaaaaaaa*bbbb",
01735 "..*************************bbbbb",
01736 "....bbbbbbbbbbbbbbbbbbbbbbbbbbb.",
01737 ".....bbbbbbbbbbbbbbbbbbbbbbbbb.."};
01738
01739 static const char* const critical_xpm[]={
01740 "32 32 4 1",
01741 ". c None",
01742 "a c #999999",
01743 "* c #ff0000",
01744 "b c #ffffff",
01745 "...........********.............",
01746 ".........************...........",
01747 ".......****************.........",
01748 "......******************........",
01749 ".....********************a......",
01750 "....**********************a.....",
01751 "...************************a....",
01752 "..*******b**********b*******a...",
01753 "..******bbb********bbb******a...",
01754 ".******bbbbb******bbbbb******a..",
01755 ".*******bbbbb****bbbbb*******a..",
01756 "*********bbbbb**bbbbb*********a.",
01757 "**********bbbbbbbbbb**********a.",
01758 "***********bbbbbbbb***********aa",
01759 "************bbbbbb************aa",
01760 "************bbbbbb************aa",
01761 "***********bbbbbbbb***********aa",
01762 "**********bbbbbbbbbb**********aa",
01763 "*********bbbbb**bbbbb*********aa",
01764 ".*******bbbbb****bbbbb*******aa.",
01765 ".******bbbbb******bbbbb******aa.",
01766 "..******bbb********bbb******aaa.",
01767 "..*******b**********b*******aa..",
01768 "...************************aaa..",
01769 "....**********************aaa...",
01770 "....a********************aaa....",
01771 ".....a******************aaa.....",
01772 "......a****************aaa......",
01773 ".......aa************aaaa.......",
01774 ".........aa********aaaaa........",
01775 "...........aaaaaaaaaaa..........",
01776 ".............aaaaaaa............"};
01777
01778 QPixmap KStyle::stylePixmap( StylePixmap stylepixmap,
01779 const QWidget* widget,
01780 const QStyleOption& opt) const
01781 {
01782 switch (stylepixmap) {
01783 case SP_TitleBarShadeButton:
01784 return QPixmap(const_cast<const char**>(kstyle_shade_xpm));
01785 case SP_TitleBarUnshadeButton:
01786 return QPixmap(const_cast<const char**>(kstyle_unshade_xpm));
01787 case SP_TitleBarNormalButton:
01788 return QPixmap(const_cast<const char**>(kstyle_normalizeup_xpm));
01789 case SP_TitleBarMinButton:
01790 return QPixmap(const_cast<const char**>(kstyle_minimize_xpm));
01791 case SP_TitleBarMaxButton:
01792 return QPixmap(const_cast<const char**>(kstyle_maximize_xpm));
01793 case SP_TitleBarCloseButton:
01794 return QPixmap(const_cast<const char**>(kstyle_close_xpm));
01795 case SP_DockWindowCloseButton:
01796 return QPixmap(const_cast<const char**>(dock_window_close_xpm ));
01797 case SP_MessageBoxInformation:
01798 return QPixmap(const_cast<const char**>(information_xpm));
01799 case SP_MessageBoxWarning:
01800 return QPixmap(const_cast<const char**>(warning_xpm));
01801 case SP_MessageBoxCritical:
01802 return QPixmap(const_cast<const char**>(critical_xpm));
01803 default:
01804 break;
01805 }
01806 return QCommonStyle::stylePixmap(stylepixmap, widget, opt);
01807 }
01808
01809
01810 int KStyle::styleHint( StyleHint sh, const QWidget* w,
01811 const QStyleOption &opt, QStyleHintReturn* shr) const
01812 {
01813 switch (sh)
01814 {
01815 case SH_EtchDisabledText:
01816 return d->etchDisabledText ? 1 : 0;
01817
01818 case SH_PopupMenu_Scrollable:
01819 return d->scrollablePopupmenus ? 1 : 0;
01820
01821 case SH_MenuBar_AltKeyNavigation:
01822 return d->menuAltKeyNavigation ? 1 : 0;
01823
01824 case SH_PopupMenu_SubMenuPopupDelay:
01825 if ( styleHint( SH_PopupMenu_SloppySubMenus, w ) )
01826 return QMIN( 100, d->popupMenuDelay );
01827 else
01828 return d->popupMenuDelay;
01829
01830 case SH_PopupMenu_SloppySubMenus:
01831 return d->sloppySubMenus;
01832
01833 case SH_ItemView_ChangeHighlightOnFocus:
01834 case SH_Slider_SloppyKeyEvents:
01835 case SH_MainWindow_SpaceBelowMenuBar:
01836 case SH_PopupMenu_AllowActiveAndDisabled:
01837 return 0;
01838
01839 case SH_Slider_SnapToValue:
01840 case SH_PrintDialog_RightAlignButtons:
01841 case SH_FontDialog_SelectAssociatedText:
01842 case SH_MenuBar_MouseTracking:
01843 case SH_PopupMenu_MouseTracking:
01844 case SH_ComboBox_ListMouseTracking:
01845 case SH_ScrollBar_MiddleClickAbsolutePosition:
01846 return 1;
01847 case SH_LineEdit_PasswordCharacter:
01848 {
01849 if (w) {
01850 const QFontMetrics &fm = w->fontMetrics();
01851 if (fm.inFont(QChar(0x25CF))) {
01852 return 0x25CF;
01853 } else if (fm.inFont(QChar(0x2022))) {
01854 return 0x2022;
01855 }
01856 }
01857 return '*';
01858 }
01859
01860 default:
01861 return QCommonStyle::styleHint(sh, w, opt, shr);
01862 }
01863 }
01864
01865
01866 bool KStyle::eventFilter( QObject* object, QEvent* event )
01867 {
01868 if ( d->useFilledFrameWorkaround )
01869 {
01870
01871
01872
01873
01874
01875
01876
01877 QFrame *frame = 0;
01878 if ( event->type() == QEvent::Paint
01879 && (frame = ::qt_cast<QFrame*>(object)) )
01880 {
01881 if (frame->frameShape() != QFrame::ToolBarPanel && frame->frameShape() != QFrame::MenuBarPanel)
01882 return false;
01883
01884 bool horizontal = true;
01885 QPaintEvent* pe = (QPaintEvent*)event;
01886 QToolBar *toolbar = ::qt_cast< QToolBar *>( frame );
01887 QRect r = pe->rect();
01888
01889 if (toolbar && toolbar->orientation() == Qt::Vertical)
01890 horizontal = false;
01891
01892 if (horizontal) {
01893 if ( r.height() == frame->height() )
01894 return false;
01895
01896
01897 QPaintEvent dummyPE( QRect( r.x(), 0, r.width(), frame->height()) );
01898 QApplication::sendEvent( frame, &dummyPE );
01899 }
01900 else {
01901 if ( r.width() == frame->width() )
01902 return false;
01903
01904 QPaintEvent dummyPE( QRect( 0, r.y(), frame->width(), r.height()) );
01905 QApplication::sendEvent( frame, &dummyPE );
01906 }
01907
01908
01909 return true;
01910 }
01911 }
01912
01913 return false;
01914 }
01915
01916
01917
01918
01919
01920
01921 TransparencyHandler::TransparencyHandler( KStyle* style,
01922 TransparencyEngine tEngine, float menuOpacity, bool useDropShadow )
01923 : QObject()
01924 {
01925 te = tEngine;
01926 kstyle = style;
01927 opacity = menuOpacity;
01928 dropShadow = useDropShadow;
01929 pix.setOptimization(QPixmap::BestOptim);
01930 }
01931
01932 TransparencyHandler::~TransparencyHandler()
01933 {
01934 }
01935
01936
01937 void TransparencyHandler::rightShadow(QImage& dst)
01938 {
01939 if (dst.depth() != 32)
01940 dst = dst.convertDepth(32);
01941
01942
01943 int pixels = dst.width() * dst.height();
01944 #ifdef WORDS_BIGENDIAN
01945 register unsigned char* data = dst.bits() + 1;
01946 #else
01947 register unsigned char* data = dst.bits();
01948 #endif
01949 for(register int i = 0; i < 16; i++) {
01950 *data = (unsigned char)((*data)*top_right_corner[i]); data++;
01951 *data = (unsigned char)((*data)*top_right_corner[i]); data++;
01952 *data = (unsigned char)((*data)*top_right_corner[i]); data++;
01953 data++;
01954 }
01955
01956 pixels -= 32;
01957 register int c = 0;
01958 for(register int i = 0; i < pixels; i++) {
01959 *data = (unsigned char)((*data)*shadow_strip[c]); data++;
01960 *data = (unsigned char)((*data)*shadow_strip[c]); data++;
01961 *data = (unsigned char)((*data)*shadow_strip[c]); data++;
01962 data++;
01963 ++c;
01964 c %= 4;
01965 }
01966
01967
01968 for(register int i = 0; i < 16; i++) {
01969 *data = (unsigned char)((*data)*bottom_right_corner[i]); data++;
01970 *data = (unsigned char)((*data)*bottom_right_corner[i]); data++;
01971 *data = (unsigned char)((*data)*bottom_right_corner[i]); data++;
01972 data++;
01973 }
01974 }
01975
01976 void TransparencyHandler::bottomShadow(QImage& dst)
01977 {
01978 if (dst.depth() != 32)
01979 dst = dst.convertDepth(32);
01980
01981 int line = 0;
01982 int width = dst.width() - 4;
01983 double strip_data = shadow_strip[0];
01984 double* corner = const_cast<double*>(bottom_left_corner);
01985
01986 #ifdef WORDS_BIGENDIAN
01987 register unsigned char* data = dst.bits() + 1;
01988 #else
01989 register unsigned char* data = dst.bits();
01990 #endif
01991
01992 for(int y = 0; y < 4; y++)
01993 {
01994
01995 for(register int x = 0; x < 4; x++) {
01996 *data = (unsigned char)((*data)*(*corner)); data++;
01997 *data = (unsigned char)((*data)*(*corner)); data++;
01998 *data = (unsigned char)((*data)*(*corner)); data++;
01999 data++;
02000 corner++;
02001 }
02002
02003
02004 for(register int x = 0; x < width; x++) {
02005 *data = (unsigned char)((*data)*strip_data); data++;
02006 *data = (unsigned char)((*data)*strip_data); data++;
02007 *data = (unsigned char)((*data)*strip_data); data++;
02008 data++;
02009 }
02010
02011 strip_data = shadow_strip[++line];
02012 }
02013 }
02014
02015
02016 void TransparencyHandler::createShadowWindows(const QWidget* p)
02017 {
02018 #ifdef Q_WS_X11
02019 int x2 = p->x()+p->width();
02020 int y2 = p->y()+p->height();
02021 QRect shadow1(x2, p->y() + 4, 4, p->height());
02022 QRect shadow2(p->x() + 4, y2, p->width() - 4, 4);
02023
02024
02025 ShadowElements se;
02026 se.w1 = new QWidget(0, 0, WStyle_Customize | WType_Popup | WX11BypassWM );
02027 se.w2 = new QWidget(0, 0, WStyle_Customize | WType_Popup | WX11BypassWM );
02028 se.w1->setGeometry(shadow1);
02029 se.w2->setGeometry(shadow2);
02030 XSelectInput(qt_xdisplay(), se.w1->winId(), StructureNotifyMask );
02031 XSelectInput(qt_xdisplay(), se.w2->winId(), StructureNotifyMask );
02032
02033
02034 shadowMap()[p] = se;
02035
02036
02037 QPixmap pix_shadow1 = QPixmap::grabWindow(qt_xrootwin(),
02038 shadow1.x(), shadow1.y(), shadow1.width(), shadow1.height());
02039 QPixmap pix_shadow2 = QPixmap::grabWindow(qt_xrootwin(),
02040 shadow2.x(), shadow2.y(), shadow2.width(), shadow2.height());
02041
02042 QImage img;
02043 img = pix_shadow1.convertToImage();
02044 rightShadow(img);
02045 pix_shadow1.convertFromImage(img);
02046 img = pix_shadow2.convertToImage();
02047 bottomShadow(img);
02048 pix_shadow2.convertFromImage(img);
02049
02050
02051 se.w1->setErasePixmap(pix_shadow1);
02052 se.w2->setErasePixmap(pix_shadow2);
02053
02054
02055
02056 XMapWindow(qt_xdisplay(), se.w1->winId());
02057 XMapWindow(qt_xdisplay(), se.w2->winId());
02058 #else
02059 Q_UNUSED( p )
02060 #endif
02061 }
02062
02063 void TransparencyHandler::removeShadowWindows(const QWidget* p)
02064 {
02065 #ifdef Q_WS_X11
02066 ShadowMap::iterator it = shadowMap().find(p);
02067 if (it != shadowMap().end())
02068 {
02069 ShadowElements se = it.data();
02070 XUnmapWindow(qt_xdisplay(), se.w1->winId());
02071 XUnmapWindow(qt_xdisplay(), se.w2->winId());
02072 XFlush(qt_xdisplay());
02073 delete se.w1;
02074 delete se.w2;
02075 shadowMap().erase(it);
02076 }
02077 #else
02078 Q_UNUSED( p )
02079 #endif
02080 }
02081
02082 bool TransparencyHandler::eventFilter( QObject* object, QEvent* event )
02083 {
02084 #if !defined Q_WS_MAC && !defined Q_WS_WIN
02085
02086
02087
02088
02089 QWidget* p = (QWidget*)object;
02090 QEvent::Type et = event->type();
02091
02092 if (et == QEvent::Show)
02093 {
02094
02095 if (te != Disabled)
02096 {
02097 pix = QPixmap::grabWindow(qt_xrootwin(),
02098 p->x(), p->y(), p->width(), p->height());
02099
02100 switch (te) {
02101 #ifdef HAVE_XRENDER
02102 case XRender:
02103 if (qt_use_xrender) {
02104 XRenderBlendToPixmap(p);
02105 break;
02106 }
02107
02108 #else
02109 case XRender:
02110 #endif
02111 case SoftwareBlend:
02112 blendToPixmap(p->colorGroup(), p);
02113 break;
02114
02115 case SoftwareTint:
02116 default:
02117 blendToColor(p->colorGroup().button());
02118 };
02119
02120 p->setErasePixmap(pix);
02121 }
02122
02123
02124
02125
02126
02127
02128 if ((dropShadow || useDropShadow(p))
02129 && p->width() > 16 && p->height() > 16 && !shadowMap().contains( p ))
02130 createShadowWindows(p);
02131 }
02132 else if (et == QEvent::Resize && p->isShown() && p->isTopLevel())
02133 {
02134
02135 if (dropShadow || useDropShadow(p))
02136 {
02137 removeShadowWindows(p);
02138 createShadowWindows(p);
02139 }
02140 }
02141 else if (et == QEvent::Hide)
02142 {
02143
02144 if (dropShadow || useDropShadow(p))
02145 removeShadowWindows(p);
02146
02147
02148 if (te != Disabled)
02149 p->setErasePixmap(QPixmap());
02150 }
02151
02152 #endif
02153 return false;
02154 }
02155
02156
02157
02158 void TransparencyHandler::blendToColor(const QColor &col)
02159 {
02160 if (opacity < 0.0 || opacity > 1.0)
02161 return;
02162
02163 QImage img = pix.convertToImage();
02164 KImageEffect::blend(col, img, opacity);
02165 pix.convertFromImage(img);
02166 }
02167
02168
02169 void TransparencyHandler::blendToPixmap(const QColorGroup &cg, const QWidget* p)
02170 {
02171 if (opacity < 0.0 || opacity > 1.0)
02172 return;
02173
02174 KPixmap blendPix;
02175 blendPix.resize( pix.width(), pix.height() );
02176
02177 if (blendPix.width() != pix.width() ||
02178 blendPix.height() != pix.height())
02179 return;
02180
02181
02182 if (::qt_cast<QPopupMenu*>(p))
02183 kstyle->renderMenuBlendPixmap( blendPix, cg, ::qt_cast<QPopupMenu*>(p) );
02184 else
02185 blendPix.fill(cg.button());
02186
02187 QImage blendImg = blendPix.convertToImage();
02188 QImage backImg = pix.convertToImage();
02189 KImageEffect::blend(blendImg, backImg, opacity);
02190 pix.convertFromImage(backImg);
02191 }
02192
02193
02194 #ifdef HAVE_XRENDER
02195
02196
02197
02198 void TransparencyHandler::XRenderBlendToPixmap(const QWidget* p)
02199 {
02200 KPixmap renderPix;
02201 renderPix.resize( pix.width(), pix.height() );
02202
02203
02204 if (::qt_cast<QPopupMenu*>(p))
02205 kstyle->renderMenuBlendPixmap( renderPix, p->colorGroup(),
02206 ::qt_cast<QPopupMenu*>(p) );
02207 else
02208 renderPix.fill(p->colorGroup().button());
02209
02210 Display* dpy = qt_xdisplay();
02211 Pixmap alphaPixmap;
02212 Picture alphaPicture;
02213 XRenderPictFormat Rpf;
02214 XRenderPictureAttributes Rpa;
02215 XRenderColor clr;
02216 clr.alpha = ((unsigned short)(255*opacity) << 8);
02217
02218 Rpf.type = PictTypeDirect;
02219 Rpf.depth = 8;
02220 Rpf.direct.alphaMask = 0xff;
02221 Rpa.repeat = True;
02222
02223 XRenderPictFormat* xformat = XRenderFindFormat(dpy,
02224 PictFormatType | PictFormatDepth | PictFormatAlphaMask, &Rpf, 0);
02225
02226 alphaPixmap = XCreatePixmap(dpy, p->handle(), 1, 1, 8);
02227 alphaPicture = XRenderCreatePicture(dpy, alphaPixmap, xformat, CPRepeat, &Rpa);
02228
02229 XRenderFillRectangle(dpy, PictOpSrc, alphaPicture, &clr, 0, 0, 1, 1);
02230
02231 XRenderComposite(dpy, PictOpOver,
02232 renderPix.x11RenderHandle(), alphaPicture, pix.x11RenderHandle(),
02233 0, 0,
02234 0, 0,
02235 0, 0,
02236 pix.width(), pix.height());
02237
02238 XRenderFreePicture(dpy, alphaPicture);
02239 XFreePixmap(dpy, alphaPixmap);
02240 }
02241 #endif
02242
02243 void KStyle::virtual_hook( int, void* )
02244 { }
02245
02246
02247
02248
02249 #include "kstyle.moc"