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