author | sandman <sandman> | 2002-11-01 16:07:10 (UTC) |
---|---|---|
committer | sandman <sandman> | 2002-11-01 16:07:10 (UTC) |
commit | 9e4d914ade0af86707531a80e93a870e52738ce6 (patch) (side-by-side diff) | |
tree | 13bcdec43e9d1afc7392ce44cd72ff1289f0c8eb | |
parent | 28b70b2b7f8fa03ba0991fb73dccf7b46e5c3d1f (diff) | |
download | opie-9e4d914ade0af86707531a80e93a870e52738ce6.zip opie-9e4d914ade0af86707531a80e93a870e52738ce6.tar.gz opie-9e4d914ade0af86707531a80e93a870e52738ce6.tar.bz2 |
Some fixes and enhancements:
- don't rely on clipping information from Qt/E -- this doesn't work
- theme style has support for all KDE gradient types now
-rw-r--r-- | noncore/styles/theme/ogfxeffect.cpp | 243 | ||||
-rw-r--r-- | noncore/styles/theme/ogfxeffect.h | 3 | ||||
-rw-r--r-- | noncore/styles/theme/othemestyle.cpp | 7 |
3 files changed, 220 insertions, 33 deletions
diff --git a/noncore/styles/theme/ogfxeffect.cpp b/noncore/styles/theme/ogfxeffect.cpp index 55f3c1f..cc5bbcd 100644 --- a/noncore/styles/theme/ogfxeffect.cpp +++ b/noncore/styles/theme/ogfxeffect.cpp @@ -1,324 +1,507 @@ /* This file is part of the KDE libraries Copyright (C) 1998, 1999 Christian Tibirna <ctibirna@total.net> (C) 1998, 1999 Daniel M. Duley <mosfet@kde.org> (C) 1998, 1999 Dirk A. Mueller <mueller@kde.org> */ // $Id$ #include <qimage.h> #include <qpainter.h> #include <qpe/qmath.h> #include "ogfxeffect.h" //====================================================================== // // Gradient effects // //====================================================================== QPixmap& OGfxEffect::gradient(QPixmap &pixmap, const QColor &ca, - const QColor &cb, GradientType eff, int /*ncols*/) + const QColor &cb, GradientType eff, int ncols) { - if(pixmap.depth() > 8 && - (eff == VerticalGradient || eff == HorizontalGradient)) { + QImage image = gradient(pixmap.size(), ca, cb, eff, ncols); + pixmap.convertFromImage(image); + + return pixmap; +} +QImage OGfxEffect::gradient(const QSize &size, const QColor &ca, + const QColor &cb, GradientType eff, int /*ncols*/) +{ int rDiff, gDiff, bDiff; - int rca, gca, bca /*, rcb, gcb, bcb*/; + int rca, gca, bca, rcb, gcb, bcb; + + QImage image(size, 32); + + if (size.width() == 0 || size.height() == 0) { + qDebug ( "WARNING: OGfxEffect::gradient: invalid image" ); + return image; + } register int x, y; - rDiff = (/*rcb = */ cb.red()) - (rca = ca.red()); - gDiff = (/*gcb = */ cb.green()) - (gca = ca.green()); - bDiff = (/*bcb = */ cb.blue()) - (bca = ca.blue()); + rDiff = (rcb = cb.red()) - (rca = ca.red()); + gDiff = (gcb = cb.green()) - (gca = ca.green()); + bDiff = (bcb = cb.blue()) - (bca = ca.blue()); + + if( eff == VerticalGradient || eff == HorizontalGradient ){ + + uint *p; + uint rgb; register int rl = rca << 16; register int gl = gca << 16; register int bl = bca << 16; - int rcdelta = ((1<<16) / (eff == VerticalGradient ? pixmap.height() : pixmap.width())) * rDiff; - int gcdelta = ((1<<16) / (eff == VerticalGradient ? pixmap.height() : pixmap.width())) * gDiff; - int bcdelta = ((1<<16) / (eff == VerticalGradient ? pixmap.height() : pixmap.width())) * bDiff; + if( eff == VerticalGradient ) { + + int rcdelta = ((1<<16) / size.height()) * rDiff; + int gcdelta = ((1<<16) / size.height()) * gDiff; + int bcdelta = ((1<<16) / size.height()) * bDiff; - QPainter p(&pixmap); + for ( y = 0; y < size.height(); y++ ) { + p = (uint *) image.scanLine(y); - // these for-loops could be merged, but the if's in the inner loop - // would make it slow - switch(eff) { - case VerticalGradient: - for ( y = 0; y < pixmap.height(); y++ ) { rl += rcdelta; gl += gcdelta; bl += bcdelta; - p.setPen(QColor(rl>>16, gl>>16, bl>>16)); - p.drawLine(0, y, pixmap.width()-1, y); + rgb = qRgb( (rl>>16), (gl>>16), (bl>>16) ); + + for( x = 0; x < size.width(); x++ ) { + *p = rgb; + p++; + } + } + } - break; - case HorizontalGradient: - for( x = 0; x < pixmap.width(); x++) { + else { // must be HorizontalGradient + + unsigned int *o_src = (unsigned int *)image.scanLine(0); + unsigned int *src = o_src; + + int rcdelta = ((1<<16) / size.width()) * rDiff; + int gcdelta = ((1<<16) / size.width()) * gDiff; + int bcdelta = ((1<<16) / size.width()) * bDiff; + + for( x = 0; x < size.width(); x++) { + rl += rcdelta; gl += gcdelta; bl += bcdelta; - p.setPen(QColor(rl>>16, gl>>16, bl>>16)); - p.drawLine(x, 0, x, pixmap.height()-1); + *src++ = qRgb( (rl>>16), (gl>>16), (bl>>16)); + } + + src = o_src; + + // Believe it or not, manually copying in a for loop is faster + // than calling memcpy for each scanline (on the order of ms...). + // I think this is due to the function call overhead (mosfet). + + for (y = 1; y < size.height(); ++y) { + + p = (unsigned int *)image.scanLine(y); + src = o_src; + for(x=0; x < size.width(); ++x) + *p++ = *src++; } - break; - default: - ; } } + else { -// QImage image = OGfxEffect::gradient(pixmap.size(), ca, cb, -// (OGfxEffect::GradientType) eff, ncols); -// pixmap.convertFromImage(image); + + float rfd, gfd, bfd; + float rd = rca, gd = gca, bd = bca; + + unsigned char *xtable[3]; + unsigned char *ytable[3]; + + unsigned int w = size.width(), h = size.height(); + xtable[0] = new unsigned char[w]; + xtable[1] = new unsigned char[w]; + xtable[2] = new unsigned char[w]; + ytable[0] = new unsigned char[h]; + ytable[1] = new unsigned char[h]; + ytable[2] = new unsigned char[h]; + w*=2, h*=2; + + if ( eff == DiagonalGradient || eff == CrossDiagonalGradient) { + // Diagonal dgradient code inspired by BlackBox (mosfet) + // BlackBox dgradient is (C) Brad Hughes, <bhughes@tcac.net> and + // Mike Cole <mike@mydot.com>. + + rfd = (float)rDiff/w; + gfd = (float)gDiff/w; + bfd = (float)bDiff/w; + + int dir; + for (x = 0; x < size.width(); x++, rd+=rfd, gd+=gfd, bd+=bfd) { + dir = eff == DiagonalGradient? x : size.width() - x - 1; + xtable[0][dir] = (unsigned char) rd; + xtable[1][dir] = (unsigned char) gd; + xtable[2][dir] = (unsigned char) bd; + } + rfd = (float)rDiff/h; + gfd = (float)gDiff/h; + bfd = (float)bDiff/h; + rd = gd = bd = 0; + for (y = 0; y < size.height(); y++, rd+=rfd, gd+=gfd, bd+=bfd) { + ytable[0][y] = (unsigned char) rd; + ytable[1][y] = (unsigned char) gd; + ytable[2][y] = (unsigned char) bd; } - return pixmap; + for (y = 0; y < size.height(); y++) { + unsigned int *scanline = (unsigned int *)image.scanLine(y); + for (x = 0; x < size.width(); x++) { + scanline[x] = qRgb(xtable[0][x] + ytable[0][y], + xtable[1][x] + ytable[1][y], + xtable[2][x] + ytable[2][y]); + } + } + } + + else if (eff == RectangleGradient || + eff == PyramidGradient || + eff == PipeCrossGradient || + eff == EllipticGradient) + { + int rSign = rDiff>0? 1: -1; + int gSign = gDiff>0? 1: -1; + int bSign = bDiff>0? 1: -1; + + rfd = (float)rDiff / size.width(); + gfd = (float)gDiff / size.width(); + bfd = (float)bDiff / size.width(); + + rd = (float)rDiff/2; + gd = (float)gDiff/2; + bd = (float)bDiff/2; + + for (x = 0; x < size.width(); x++, rd-=rfd, gd-=gfd, bd-=bfd) + { + xtable[0][x] = (unsigned char) abs((int)rd); + xtable[1][x] = (unsigned char) abs((int)gd); + xtable[2][x] = (unsigned char) abs((int)bd); + } + + rfd = (float)rDiff/size.height(); + gfd = (float)gDiff/size.height(); + bfd = (float)bDiff/size.height(); + + rd = (float)rDiff/2; + gd = (float)gDiff/2; + bd = (float)bDiff/2; + + for (y = 0; y < size.height(); y++, rd-=rfd, gd-=gfd, bd-=bfd) + { + ytable[0][y] = (unsigned char) abs((int)rd); + ytable[1][y] = (unsigned char) abs((int)gd); + ytable[2][y] = (unsigned char) abs((int)bd); + } + unsigned int rgb; + int h = (size.height()+1)>>1; + for (y = 0; y < h; y++) { + unsigned int *sl1 = (unsigned int *)image.scanLine(y); + unsigned int *sl2 = (unsigned int *)image.scanLine(QMAX(size.height()-y-1, y)); + + int w = (size.width()+1)>>1; + int x2 = size.width()-1; + + for (x = 0; x < w; x++, x2--) { + rgb = 0; + if (eff == PyramidGradient) { + rgb = qRgb(rcb-rSign*(xtable[0][x]+ytable[0][y]), + gcb-gSign*(xtable[1][x]+ytable[1][y]), + bcb-bSign*(xtable[2][x]+ytable[2][y])); + } + if (eff == RectangleGradient) { + rgb = qRgb(rcb - rSign * + QMAX(xtable[0][x], ytable[0][y]) * 2, + gcb - gSign * + QMAX(xtable[1][x], ytable[1][y]) * 2, + bcb - bSign * + QMAX(xtable[2][x], ytable[2][y]) * 2); + } + if (eff == PipeCrossGradient) { + rgb = qRgb(rcb - rSign * + QMIN(xtable[0][x], ytable[0][y]) * 2, + gcb - gSign * + QMIN(xtable[1][x], ytable[1][y]) * 2, + bcb - bSign * + QMIN(xtable[2][x], ytable[2][y]) * 2); + } + if (eff == EllipticGradient) { + rgb = qRgb(rcb - rSign * + (int)sqrt((xtable[0][x]*xtable[0][x] + + ytable[0][y]*ytable[0][y])*2.0), + gcb - gSign * + (int)sqrt((xtable[1][x]*xtable[1][x] + + ytable[1][y]*ytable[1][y])*2.0), + bcb - bSign * + (int)sqrt((xtable[2][x]*xtable[2][x] + + ytable[2][y]*ytable[2][y])*2.0)); + } + + sl1[x] = sl2[x] = rgb; + sl1[x2] = sl2[x2] = rgb; + } + } + } + + delete [] xtable[0]; + delete [] xtable[1]; + delete [] xtable[2]; + delete [] ytable[0]; + delete [] ytable[1]; + delete [] ytable[2]; + } + return image; } //====================================================================== // // Blend effects // //====================================================================== QPixmap& OGfxEffect::blend(QPixmap &pixmap, float initial_intensity, const QColor &bgnd, GradientType eff, bool anti_dir, int /*ncols*/) { QImage image = pixmap.convertToImage(); OGfxEffect::blend(image, initial_intensity, bgnd, eff, anti_dir); if ( pixmap. depth ( ) <= 8 ) image. convertDepth ( pixmap. depth ( )); pixmap.convertFromImage(image); return pixmap; } QImage& OGfxEffect::blend(QImage &image, float initial_intensity, const QColor &bgnd, GradientType eff, bool anti_dir) { if (image.width() == 0 || image.height() == 0) { qDebug ( "Invalid image\n" ); return image; } int r_bgnd = bgnd.red(), g_bgnd = bgnd.green(), b_bgnd = bgnd.blue(); int r, g, b; int ind; unsigned int xi, xf, yi, yf; unsigned int a; // check the boundaries of the initial intesity param float unaffected = 1; if (initial_intensity > 1) initial_intensity = 1; if (initial_intensity < -1) initial_intensity = -1; if (initial_intensity < 0) { unaffected = 1. + initial_intensity; initial_intensity = 0; } float intensity = initial_intensity; float var = 1. - initial_intensity; if (anti_dir) { initial_intensity = intensity = 1.; var = -var; } register int x, y; unsigned int *data = (unsigned int *)image.bits(); if( eff == VerticalGradient || eff == HorizontalGradient ) { // set the image domain to apply the effect to xi = 0, xf = image.width(); yi = 0, yf = image.height(); if (eff == VerticalGradient) { if (anti_dir) yf = (int)(image.height() * unaffected); else yi = (int)(image.height() * (1 - unaffected)); } else { if (anti_dir) xf = (int)(image.width() * unaffected); else xi = (int)(image.height() * (1 - unaffected)); } var /= (eff == VerticalGradient?yf-yi:xf-xi); for (y = yi; y < (int)yf; y++) { intensity = eff == VerticalGradient? intensity + var : initial_intensity; for (x = xi; x < (int)xf ; x++) { if (eff == HorizontalGradient) intensity += var; ind = x + image.width() * y ; r = qRed (data[ind]) + (int)(intensity * (r_bgnd - qRed (data[ind]))); g = qGreen(data[ind]) + (int)(intensity * (g_bgnd - qGreen(data[ind]))); b = qBlue (data[ind]) + (int)(intensity * (b_bgnd - qBlue (data[ind]))); if (r > 255) r = 255; if (r < 0 ) r = 0; if (g > 255) g = 255; if (g < 0 ) g = 0; if (b > 255) b = 255; if (b < 0 ) b = 0; a = qAlpha(data[ind]); data[ind] = qRgba(r, g, b, a); } } } else if (eff == DiagonalGradient || eff == CrossDiagonalGradient) { float xvar = var / 2 / image.width(); // / unaffected; float yvar = var / 2 / image.height(); // / unaffected; float tmp; for (x = 0; x < image.width() ; x++) { tmp = xvar * (eff == DiagonalGradient? x : image.width()-x-1); for (y = 0; y < image.height() ; y++) { intensity = initial_intensity + tmp + yvar * y; ind = x + image.width() * y ; r = qRed (data[ind]) + (int)(intensity * (r_bgnd - qRed (data[ind]))); g = qGreen(data[ind]) + (int)(intensity * (g_bgnd - qGreen(data[ind]))); b = qBlue (data[ind]) + (int)(intensity * (b_bgnd - qBlue (data[ind]))); if (r > 255) r = 255; if (r < 0 ) r = 0; if (g > 255) g = 255; if (g < 0 ) g = 0; if (b > 255) b = 255; if (b < 0 ) b = 0; a = qAlpha(data[ind]); data[ind] = qRgba(r, g, b, a); } } } else if (eff == RectangleGradient || eff == EllipticGradient) { float xvar; float yvar; for (x = 0; x < image.width() / 2 + image.width() % 2; x++) { xvar = var / image.width() * (image.width() - x*2/unaffected-1); for (y = 0; y < image.height() / 2 + image.height() % 2; y++) { yvar = var / image.height() * (image.height() - y*2/unaffected -1); if (eff == RectangleGradient) intensity = initial_intensity + QMAX(xvar, yvar); else intensity = initial_intensity + qSqrt(xvar * xvar + yvar * yvar); if (intensity > 1) intensity = 1; if (intensity < 0) intensity = 0; //NW ind = x + image.width() * y ; r = qRed (data[ind]) + (int)(intensity * (r_bgnd - qRed (data[ind]))); g = qGreen(data[ind]) + (int)(intensity * (g_bgnd - qGreen(data[ind]))); b = qBlue (data[ind]) + (int)(intensity * (b_bgnd - qBlue (data[ind]))); if (r > 255) r = 255; if (r < 0 ) r = 0; if (g > 255) g = 255; if (g < 0 ) g = 0; if (b > 255) b = 255; if (b < 0 ) b = 0; a = qAlpha(data[ind]); data[ind] = qRgba(r, g, b, a); //NE ind = image.width() - x - 1 + image.width() * y ; r = qRed (data[ind]) + (int)(intensity * (r_bgnd - qRed (data[ind]))); g = qGreen(data[ind]) + (int)(intensity * (g_bgnd - qGreen(data[ind]))); b = qBlue (data[ind]) + (int)(intensity * (b_bgnd - qBlue (data[ind]))); if (r > 255) r = 255; if (r < 0 ) r = 0; if (g > 255) g = 255; if (g < 0 ) g = 0; if (b > 255) b = 255; if (b < 0 ) b = 0; a = qAlpha(data[ind]); data[ind] = qRgba(r, g, b, a); } } //CT loop is doubled because of stupid central row/column issue. // other solution? for (x = 0; x < image.width() / 2; x++) { xvar = var / image.width() * (image.width() - x*2/unaffected-1); for (y = 0; y < image.height() / 2; y++) { yvar = var / image.height() * (image.height() - y*2/unaffected -1); if (eff == RectangleGradient) intensity = initial_intensity + QMAX(xvar, yvar); else intensity = initial_intensity + qSqrt(xvar * xvar + yvar * yvar); if (intensity > 1) intensity = 1; if (intensity < 0) intensity = 0; //SW ind = x + image.width() * (image.height() - y -1) ; r = qRed (data[ind]) + (int)(intensity * (r_bgnd - qRed (data[ind]))); g = qGreen(data[ind]) + (int)(intensity * (g_bgnd - qGreen(data[ind]))); b = qBlue (data[ind]) + (int)(intensity * (b_bgnd - qBlue (data[ind]))); if (r > 255) r = 255; if (r < 0 ) r = 0; if (g > 255) g = 255; if (g < 0 ) g = 0; if (b > 255) b = 255; if (b < 0 ) b = 0; a = qAlpha(data[ind]); data[ind] = qRgba(r, g, b, a); //SE ind = image.width()-x-1 + image.width() * (image.height() - y - 1) ; r = qRed (data[ind]) + (int)(intensity * (r_bgnd - qRed (data[ind]))); g = qGreen(data[ind]) + (int)(intensity * (g_bgnd - qGreen(data[ind]))); b = qBlue (data[ind]) + (int)(intensity * (b_bgnd - qBlue (data[ind]))); if (r > 255) r = 255; if (r < 0 ) r = 0; if (g > 255) g = 255; if (g < 0 ) g = 0; if (b > 255) b = 255; if (b < 0 ) b = 0; a = qAlpha(data[ind]); data[ind] = qRgba(r, g, b, a); } } } else qDebug ( "not implemented\n" ); return image; } #if 0 // Not very efficient as we create a third big image... // QImage& KQGfxEffect::blend(QImage &image1, QImage &image2, GradientType gt, int xf, int yf) { if (image1.width() == 0 || image1.height() == 0 || image2.width() == 0 || image2.height() == 0) return image1; QImage image3; image3 = KQGfxEffect::unbalancedGradient(image1.size(), QColor(0,0,0), QColor(255,255,255), gt, xf, yf, 0); return blend(image1,image2,image3, Red); // Channel to use is arbitrary } #endif diff --git a/noncore/styles/theme/ogfxeffect.h b/noncore/styles/theme/ogfxeffect.h index 45a8482..755537f 100644 --- a/noncore/styles/theme/ogfxeffect.h +++ b/noncore/styles/theme/ogfxeffect.h @@ -1,78 +1,81 @@ /* This file is part of the KDE libraries Copyright (C) 1998, 1999 Christian Tibirna <ctibirna@total.net> (C) 1998, 1999 Daniel M. Duley <mosfet@kde.org> (C) 1998, 1999 Dirk A. Mueller <mueller@kde.org> */ // $Id$ #ifndef __OGFX_EFFECT_H #define __OGFX_EFFECT_H #include <qpixmap.h> #include <qimage.h> /** * This class includes various pixmap-based graphical effects. * * Everything is * static, so there is no need to create an instance of this class. You can * just call the static methods. They are encapsulated here merely to provide * a common namespace. */ class OGfxEffect { public: enum GradientType { VerticalGradient, HorizontalGradient, DiagonalGradient, CrossDiagonalGradient, PyramidGradient, RectangleGradient, PipeCrossGradient, EllipticGradient }; enum RGBComponent { Red, Green, Blue }; enum Lighting {NorthLite, NWLite, WestLite, SWLite, SouthLite, SELite, EastLite, NELite}; /** * Create a gradient from color a to color b of the specified type. * * @param pixmap The pixmap to process. * @param ca Color a. * @param cb Color b. * @param type The type of gradient. * @param ncols The number of colors to use when not running on a * truecolor display. The gradient will be dithered to this number of * colors. Pass 0 to prevent dithering. * @return Returns the generated pixmap, for convenience. */ static QPixmap& gradient(QPixmap& pixmap, const QColor &ca, const QColor &cb, GradientType type, int ncols=3); + static QImage gradient (const QSize &size, const QColor &ca, const QColor &cb, + GradientType type, int ncols=3); + /** * Blend the provided pixmap into a background of the indicated color * * @param pixmap The pixmap to process. * @param initial_intensity this parameter takes values from -1 to 1: * @li If positive, it tells how much to fade the image in its * less affected spot. * @li If negative, it tells roughly indicates how much of the image * remains unaffected * @param bgnd Indicates the color of the background to blend in. * @param eff Lets you choose what kind of blending you like. * @param anti_dir Blend in the opposite direction (makes no much sense * with concentric blending effects). * @return Returns the @ref pixmap(), provided for convenience. */ static QPixmap& blend(QPixmap& pixmap, float initial_intensity, const QColor &bgnd, GradientType eff, bool anti_dir=false, int ncols=3); static QImage& blend(QImage &image, float initial_intensity, const QColor &bgnd, GradientType eff, bool anti_dir); }; #endif diff --git a/noncore/styles/theme/othemestyle.cpp b/noncore/styles/theme/othemestyle.cpp index d97b026..8c7a71b 100644 --- a/noncore/styles/theme/othemestyle.cpp +++ b/noncore/styles/theme/othemestyle.cpp @@ -189,1352 +189,1353 @@ void OThemeStyle::drawBaseButton( QPainter *p, int x, int y, int w, int h, *scalePixmap( w - 6, h - 6, type ) ); else p->fillRect( x + 4, y + 4, w - 6, h - offset * 6, g.brush( QColorGroup::Button ) ); } else { if ( ( w - offset * 2 ) > 0 && ( h - offset * 2 ) > 0 ) { if ( isPixmap( type ) ) if ( rounded ) p->drawTiledPixmap( x, y, w, h, *scalePixmap( w, h, type ) ); else p->drawTiledPixmap( x + offset, y + offset, w - offset * 2, h - offset * 2, *scalePixmap( w - offset * 2, h - offset * 2, type ) ); else p->fillRect( x + offset, y + offset, w - offset * 2, h - offset * 2, g.brush( QColorGroup::Button ) ); } if ( borderPixmap( type ) ) bitBlt( p->device(), x, y, scaleBorder( w, h, type ), 0, 0, w, h, Qt::CopyROP, false ); else drawShade( p, x, y, w, h, g, sunken, rounded, highlightWidth( type ), borderWidth( type ), shade() ); } p->setPen( oldPen ); } void OThemeStyle::drawButton( QPainter *p, int x, int y, int w, int h, const QColorGroup &g, bool sunken, const QBrush *fill ) { drawBaseButton( p, x, y, w, h, g, sunken, roundButton(), sunken ? PushButtonDown : PushButton, fill ); } void OThemeStyle::drawPushButton( QPushButton* btn, QPainter *p ) { bool sunken = btn->isOn() || btn->isDown(); int diw = buttonDefaultIndicatorWidth(); drawBaseButton( p, diw, diw, btn->width() - 2 * diw, btn->height() - 2 * diw, *colorGroup( btn->colorGroup(), sunken ? PushButtonDown : PushButton ), sunken, roundButton(), sunken ? PushButtonDown : PushButton, NULL ); // TODO if diw, draw fancy default button indicator } void OThemeStyle::drawBaseMask( QPainter *p, int x, int y, int w, int h, bool round ) { // round edge fills static const QCOORD btm_left_fill[] = { 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 0, 1, 1, 1, 2, 1, 3, 1, 4, 1, 1, 2, 2, 2, 3, 2, 4, 2, 2, 3, 3, 3, 4, 3, 3, 4, 4, 4 }; static const QCOORD btm_right_fill[] = { 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 0, 1, 1, 1, 2, 1, 3, 1, 4, 1, 0, 2, 1, 2, 2, 2, 3, 2, 0, 3, 1, 3, 2, 3, 0, 4, 1, 4 }; static const QCOORD top_left_fill[] = { 3, 0, 4, 0, 2, 1, 3, 1, 4, 1, 1, 2, 2, 2, 3, 2, 4, 2, 0, 3, 1, 3, 2, 3, 3, 3, 4, 3, 0, 4, 1, 4, 2, 4, 3, 4, 4, 4 }; static const QCOORD top_right_fill[] = { 0, 0, 1, 0, 0, 1, 1, 1, 2, 1, 0, 2, 1, 2, 2, 2, 3, 2, 0, 3, 1, 3, 2, 3, 3, 3, 4, 3, 0, 4, 1, 4, 2, 4, 3, 4, 4, 4 }; QBrush fillBrush( color1, SolidPattern ); p->setPen( color1 ); if ( round && w > 19 && h > 19 ) { int x2 = x + w - 1; int y2 = y + h - 1; QPointArray a( QCOORDARRLEN( top_left_fill ), top_left_fill ); a.translate( 1, 1 ); p->drawPoints( a ); a.setPoints( QCOORDARRLEN( btm_left_fill ), btm_left_fill ); a.translate( 1, h - 6 ); p->drawPoints( a ); a.setPoints( QCOORDARRLEN( top_right_fill ), top_right_fill ); a.translate( w - 6, 1 ); p->drawPoints( a ); a.setPoints( QCOORDARRLEN( btm_right_fill ), btm_right_fill ); a.translate( w - 6, h - 6 ); p->drawPoints( a ); p->fillRect( x + 6, y, w - 12, h, fillBrush ); p->fillRect( x, y + 6, x + 6, h - 12, fillBrush ); p->fillRect( x2 - 6, y + 6, x2, h - 12, fillBrush ); p->drawLine( x + 6, y, x2 - 6, y ); p->drawLine( x + 6, y2, x2 - 6, y2 ); p->drawLine( x, y + 6, x, y2 - 6 ); p->drawLine( x2, y + 6, x2, y2 - 6 ); } else p->fillRect( x, y, w, h, fillBrush ); } void OThemeStyle::drawButtonMask( QPainter *p, int x, int y, int w, int h ) { drawBaseMask( p, x, y, w, h, roundButton() ); } void OThemeStyle::drawComboButtonMask( QPainter *p, int x, int y, int w, int h ) { drawBaseMask( p, x, y, w, h, roundComboBox() ); } void OThemeStyle::drawBevelButton( QPainter *p, int x, int y, int w, int h, const QColorGroup &g, bool sunken, const QBrush * ) { WidgetType type = sunken ? BevelDown : Bevel; drawBaseButton( p, x, y, w, h, *colorGroup( g, type ), sunken, false, type ); } void OThemeStyle::drawToolButton( QPainter *p, int x, int y, int w, int h, const QColorGroup &g, bool sunken, const QBrush * ) { WidgetType type = sunken ? ToolButtonDown : ToolButton; drawBaseButton( p, x, y, w, h, *colorGroup( g, type ), sunken, false, type ); } #if 0 void OThemeStyle::drawKToolBarButton( QPainter *p, int x, int y, int w, int h, const QColorGroup &g, bool sunken, bool raised, bool enabled, bool popup, KToolButtonType type, const QString &btext, const QPixmap *pixmap, QFont *font, QWidget * ) { QFont tmp_font( QString::fromLatin1( "Helvetica" ), 10 ); if ( font ) tmp_font = *font; QFontMetrics fm( tmp_font ); WidgetType widget = sunken ? ToolButtonDown : ToolButton; drawBaseButton( p, x, y, w, h, *colorGroup( g, widget ), sunken, false, widget ); int dx, dy; if ( type == Icon ) { // icon only if ( pixmap ) { dx = ( w - pixmap->width() ) / 2; dy = ( h - pixmap->height() ) / 2; if ( sunken ) { ++dx; ++dy; } p->drawPixmap( x + dx, y + dy, *pixmap ); } } else if ( type == IconTextRight ) { // icon and text (if any) if ( pixmap ) { dx = 4; dy = ( h - pixmap->height() ) / 2; if ( sunken ) { ++dx; ++dy; } p->drawPixmap( x + dx, y + dy, *pixmap ); } if ( !btext.isNull() ) { int tf = AlignVCenter | AlignLeft; if ( pixmap ) dx = 4 + pixmap->width() + 2; else dx = 4; dy = 0; if ( sunken ) { ++dx; ++dy; } if ( font ) p->setFont( *font ); if ( raised ) p->setPen( KGlobalSettings::toolBarHighlightColor() ); p->drawText( x + dx, y + dy, w - dx, h, tf, btext ); } } else if ( type == Text ) { // only text, even if there is a icon if ( !btext.isNull() ) { int tf = AlignTop | AlignLeft; if ( !enabled ) p->setPen( g.dark() ); dx = ( w - fm.width( btext ) ) / 2; dy = ( h - fm.lineSpacing() ) / 2; if ( sunken ) { ++dx; ++dy; } if ( font ) p->setFont( *font ); if ( raised ) p->setPen( KGlobalSettings::toolBarHighlightColor() ); p->drawText( x + dx, y + dy, fm.width( btext ), fm.lineSpacing(), tf, btext ); } } else if ( type == IconTextBottom ) { if ( pixmap ) { dx = ( w - pixmap->width() ) / 2; dy = ( h - fm.lineSpacing() - pixmap->height() ) / 2; if ( sunken ) { ++dx; ++dy; } p->drawPixmap( x + dx, y + dy, *pixmap ); } if ( !btext.isNull() ) { int tf = AlignBottom | AlignHCenter; dx = ( w - fm.width( btext ) ) / 2; dy = h - fm.lineSpacing() - 4; if ( sunken ) { ++dx; ++dy; } if ( font ) p->setFont( *font ); if ( raised ) p->setPen( KGlobalSettings::toolBarHighlightColor() ); p->drawText( x + dx, y + dy, fm.width( btext ), fm.lineSpacing(), tf, btext ); } } if ( popup ) { if ( enabled ) qDrawArrow ( p, DownArrow, WindowsStyle, false, w - 5, h - 5, 0, 0, g, true ); else qDrawArrow ( p, DownArrow, WindowsStyle, false, w - 5, h - 5, 0, 0, g, false ); } } void OThemeStyle::drawKBarHandle( QPainter *p, int x, int y, int w, int h, const QColorGroup &g, KToolBarPos, QBrush * ) { if ( w > h ) drawBaseButton( p, x, y, w, h, *colorGroup( g, HBarHandle ), false, false, HBarHandle ); else drawBaseButton( p, x, y, w, h, *colorGroup( g, VBarHandle ), false, false, VBarHandle ); } void OThemeStyle::drawKToolBar( QPainter *p, int x, int y, int w, int h, const QColorGroup &g, KToolBarPos, QBrush * ) { drawBaseButton( p, x, y, w, h, *colorGroup( g, ToolBar ), false, false, ToolBar ); } #endif QRect OThemeStyle::buttonRect( int x, int y, int w, int h ) { int spacing = decoWidth( PushButton ) > decoWidth( PushButtonDown ) ? decoWidth( PushButton ) : decoWidth( PushButtonDown ); return ( QRect( x + spacing, y + spacing, w - ( spacing * 2 ), h - ( spacing * 2 ) ) ); } void OThemeStyle::drawComboButton( QPainter *p, int x, int y, int w, int h, const QColorGroup &g, bool sunken, bool, bool, const QBrush * ) { WidgetType widget = sunken ? ComboBoxDown : ComboBox; drawBaseButton( p, x, y, w, h, *colorGroup( g, widget ), sunken, roundComboBox(), widget ); if ( !sunken && isPixmap( ComboDeco ) ) p->drawPixmap( w - uncached( ComboDeco ) ->width() - decoWidth( ComboBox ) - 2, y + ( h - uncached( ComboDeco ) -> height() ) / 2, *uncached( ComboDeco ) ); else if ( sunken && isPixmap( ComboDecoDown ) ) p->drawPixmap( w - uncached( ComboDecoDown ) ->width() - decoWidth( ComboBoxDown ) - 2, y + ( h - uncached( ComboDecoDown ) -> height() ) / 2, *uncached( ComboDecoDown ) ); else { qDrawArrow( p, Qt::DownArrow, Qt::MotifStyle, false, w - 15, y + 6, 10, h - 15, *colorGroup( g, widget ), true ); qDrawShadeRect( p, w - 14, y + 7 + ( h - 15 ), 10, 3, *colorGroup( g, widget ) ); } } void OThemeStyle::drawScrollBarControls( QPainter *p, const QScrollBar *sb, int sliderStart, uint controls, uint activeControl ) { int sliderMin, sliderMax, sliderLength, buttonDim; QRect add , sub, addPage, subPage, slider; int addX, addY, subX, subY; bool horizontal = sb->orientation() == QScrollBar::Horizontal; int len = ( horizontal ) ? sb->width() : sb->height(); int extent = ( horizontal ) ? sb->height() : sb->width(); int offset = decoWidth( horizontal ? HScrollGroove : VScrollGroove ); QColorGroup g = sb->colorGroup(); scrollBarMetrics( sb, sliderMin, sliderMax, sliderLength, buttonDim ); if ( sliderStart > sliderMax ) sliderStart = sliderMax; int sliderEnd = sliderStart + sliderLength; int sliderWidth = extent - offset * 2; // Scary button placement code >:-P Feel free to improve this if you // want. I get a headache just looking at it... (mosfet) if ( scrollBarLayout() == SBOpposite ) { if ( horizontal ) { subY = addY = ( extent - buttonDim ) / 2; subX = offset; addX = len - buttonDim - offset; } else { subX = addX = ( extent - buttonDim ) / 2; subY = offset; addY = len - buttonDim - offset; } sub.setRect( subX, subY, buttonDim, buttonDim ); add.setRect( addX, addY, buttonDim, buttonDim ); if ( horizontal ) { subPage.setRect( sub.right() + 1, offset, sliderStart - sub.right() - 1 , sliderWidth ); addPage.setRect( sliderEnd, offset, addX - sliderEnd, sliderWidth ); slider.setRect( sliderStart, offset, sliderLength, sliderWidth ); } else { subPage.setRect( offset, sub.bottom() + 1, sliderWidth, sliderStart - sub.bottom() - 1 ); addPage.setRect( offset, sliderEnd, sliderWidth, addY - sliderEnd ); slider.setRect( offset, sliderStart, sliderWidth, sliderLength ); } } else if ( horizontal ) { subY = addY = ( extent - buttonDim ) / 2; if ( scrollBarLayout() == SBBottomLeft ) { subX = offset; addX = buttonDim + offset; subPage.setRect( buttonDim * 2, 0, sliderStart - 1, extent ); addPage.setRect( sliderEnd, 0, len - sliderEnd, extent ); slider.setRect( sliderStart, 0, sliderLength, extent ); } else { subX = len - buttonDim - buttonDim - offset; addX = len - buttonDim - offset; subPage.setRect( offset + 1, offset, sliderStart - 1 , sliderWidth ); addPage.setRect( sliderEnd, offset, subX - sliderEnd, sliderWidth ); slider.setRect( sliderStart, offset, sliderLength, sliderWidth ); } sub.setRect( subX, subY, buttonDim, buttonDim ); add.setRect( addX, addY, buttonDim, buttonDim ); } else { // BottomLeft and BottomRight vertical bars are the same. subX = addX = ( extent - buttonDim ) / 2; subY = len - buttonDim - buttonDim - offset; addY = len - buttonDim - offset; subPage.setRect( offset, offset + 1, sliderWidth, sliderStart - offset - 1 ); addPage.setRect( offset, sliderEnd, sliderWidth, subY - sliderEnd ); slider.setRect( offset, sliderStart, sliderWidth, sliderLength ); sub.setRect( subX, subY, buttonDim, buttonDim ); add.setRect( addX, addY, buttonDim, buttonDim ); } // End of the button placement code bool active; if ( ( controls & QStyle::SubPage ) ) { drawScrollBarGroove( p, sb, horizontal, subPage, g ); } if ( ( controls & QStyle::AddPage ) ) { drawScrollBarGroove( p, sb, horizontal, addPage, g ); } if ( controls & QStyle::AddLine ) { active = activeControl == QStyle::AddLine; drawBaseButton( p, add.x(), add.y(), add.width(), add.height(), *colorGroup( g, active ? ScrollButtonDown : ScrollButton ), active, false, active ? ScrollButtonDown : ScrollButton ); drawArrow( p, ( horizontal ) ? RightArrow : DownArrow, active, add.x() + 3, add.y() + 3, add.width() - 6, add.height() - 6, *colorGroup( g, active ? ScrollButtonDown : ScrollButton ) ); } if ( controls & QStyle::SubLine ) { active = activeControl == QStyle::SubLine; p->setPen( g.dark() ); p->drawRect( sub ); drawBaseButton( p, sub.x(), sub.y(), sub.width(), sub.height(), *colorGroup( g, active ? ScrollButtonDown : ScrollButton ), active, false, active ? ScrollButtonDown : ScrollButton ); drawArrow( p, ( horizontal ) ? LeftArrow : UpArrow, active, sub.x() + 3, sub.y() + 3, sub.width() - 6, sub.height() - 6, *colorGroup( g, active ? ScrollButtonDown : ScrollButton ) ); } if ( controls & QStyle::Slider ) { active = activeControl == QStyle::Slider; WidgetType widget = horizontal ? active ? HScrollBarSliderDown : HScrollBarSlider : active ? VScrollBarSliderDown : VScrollBarSlider; drawBaseButton( p, slider.x(), slider.y(), slider.width(), slider.height(), *colorGroup( g, widget ), active, false, widget ); int spaceW = horizontal ? slider.width() - decoWidth( widget ) - 4 : slider.width(); int spaceH = horizontal ? slider.height() : slider.height() - decoWidth( widget ) - 4; widget = active ? horizontal ? HScrollDecoDown : VScrollDecoDown : horizontal ? HScrollDeco : VScrollDeco; if ( isPixmap( widget ) ) { if ( spaceW >= uncached( widget ) ->width() && spaceH >= uncached( widget ) ->height() ) { p->drawPixmap( slider.x() + ( slider.width() - uncached( widget ) ->width() ) / 2, slider.y() + ( slider.height() - uncached( widget ) ->height() ) / 2, *uncached( widget ) ); } } } } void OThemeStyle::drawScrollBarGroove( QPainter *p, const QScrollBar *sb, bool horizontal, QRect r, QColorGroup g ) { WidgetType widget = ( horizontal ) ? HScrollGroove : VScrollGroove; if ( !isPixmap( widget ) ) { p->fillRect( r, colorGroup( g, widget ) ->brush( QColorGroup::Background ) ); } else { // If the groove is pixmapped we make a full-sized image (it gets // cached) then bitBlt it to the appropriate rect. QPixmap buffer( sb->size() ); QPainter bPainter( &buffer ); bPainter.drawTiledPixmap( 0, 0, buffer.width(), buffer.height(), *scalePixmap( buffer.width(), buffer.height(), widget ) ); bitBlt( p->device(), r.x(), r.y(), &buffer, r.x(), r.y(), r.width(), r.height(), Qt::CopyROP ); } // Do the borders and frame drawShade( p, sb->rect().x(), sb->rect().y(), sb->rect().width(), sb->rect().height(), *colorGroup( g, widget ), true, false, highlightWidth( widget ), borderWidth( widget ), shade() ); } void OThemeStyle::scrollBarMetrics( const QScrollBar *sb, int &sliderMin, int &sliderMax, int &sliderLength, int &buttonDim ) { bool horizontal = sb->orientation() == QScrollBar::Horizontal; int offset = decoWidth( horizontal ? HScrollGroove : VScrollGroove ); int maxlen; int len = horizontal ? sb->width() : sb->height(); int extent = horizontal ? sb->height() : sb->width(); if ( len > ( extent - offset * 2 - 1 ) * 2 + offset * 2 ) buttonDim = extent - offset * 2; else buttonDim = ( len - offset * 2 ) / 2 - 1; maxlen = len - offset * 2 - buttonDim * 2 - 1; switch ( scrollBarLayout() ) { case SBBottomLeft: sliderMin = ( horizontal ) ? buttonDim * 2 + offset + 1 : offset + 1; break; case SBBottomRight: sliderMin = offset + 1; break; case SBOpposite: default: sliderMin = offset + buttonDim; break; } if ( sb->maxValue() == sb->minValue() ) sliderLength = maxlen; else sliderLength = ( sb->pageStep() * maxlen ) / ( sb->maxValue() - sb->minValue() + sb->pageStep() ); if ( sliderLength < 12 || ( sb->maxValue() - sb->minValue() ) > INT_MAX / 2 ) sliderLength = 12; if ( sliderLength > maxlen ) sliderLength = maxlen; sliderMax = sliderMin + maxlen - sliderLength; } QStyle::ScrollControl OThemeStyle::scrollBarPointOver( const QScrollBar *sb, int sliderStart, const QPoint &p ) { if ( !sb->rect().contains( p ) ) return ( QStyle::NoScroll ); int sliderMin, sliderMax, sliderLength, buttonDim; int pos = ( sb->orientation() == QScrollBar::Horizontal ) ? p.x() : p.y(); scrollBarMetrics( sb, sliderMin, sliderMax, sliderLength, buttonDim ); if ( scrollBarLayout() == SBOpposite ) { if ( pos < sliderMin ) return QStyle::SubLine; if ( pos < sliderStart ) return SubPage; if ( pos < sliderStart + sliderLength ) return QStyle::Slider; if ( pos < sliderMax + sliderLength ) return QStyle::AddPage; return QStyle::AddLine; } if ( scrollBarLayout() == SBBottomLeft && sb->orientation() == QScrollBar::Horizontal ) { if ( pos <= buttonDim ) return ( QStyle::SubLine ); else if ( pos <= buttonDim * 2 ) return ( QStyle::AddLine ); else if ( pos < sliderStart ) return ( QStyle::SubPage ); else if ( pos < sliderStart + sliderLength ) return ( QStyle::Slider ); return ( AddPage ); } else { if ( pos < sliderStart ) return QStyle::SubPage; if ( pos < sliderStart + sliderLength ) return QStyle::Slider; if ( pos < sliderMax + sliderLength ) return QStyle::AddPage; if ( pos < sliderMax + sliderLength + buttonDim ) return QStyle::SubLine; return QStyle::AddLine; } } QSize OThemeStyle::exclusiveIndicatorSize() const { if ( isPixmap( ExIndicatorOn ) ) return ( uncached( ExIndicatorOn ) ->size() ); else return ( QWindowsStyle::exclusiveIndicatorSize() ); } QSize OThemeStyle::indicatorSize() const { if ( isPixmap( IndicatorOn ) ) return ( uncached( IndicatorOn ) ->size() ); else return ( QWindowsStyle::indicatorSize() ); } void OThemeStyle::drawExclusiveIndicator( QPainter* p, int x, int y, int w, int h, const QColorGroup &g, bool on, bool down, bool enabled ) { if ( isPixmap( ( on || down ) ? ExIndicatorOn : ExIndicatorOff ) ) { p->drawPixmap( x, y, *uncached( ( on || down ) ? ExIndicatorOn : ExIndicatorOff ) ); } else { QWindowsStyle::drawExclusiveIndicator( p, x, y, w, h, *colorGroup( g, ExIndicatorOn ), on, down, enabled ); } } void OThemeStyle::drawIndicator( QPainter* p, int x, int y, int w, int h, const QColorGroup &g, int state, bool down, bool enabled ) { if ( isPixmap( ( down || state != QButton::Off ) ? IndicatorOn : IndicatorOff ) ) { p->drawPixmap( x, y, *uncached( ( down || state != QButton::Off ) ? IndicatorOn : IndicatorOff ) ); } else { QWindowsStyle::drawIndicator( p, x, y, w, h, *colorGroup( g, IndicatorOn ), state, down, enabled ); } } void OThemeStyle::drawExclusiveIndicatorMask( QPainter *p, int x, int y, int w, int h, bool on ) { if ( isPixmap( ( on ) ? ExIndicatorOn : ExIndicatorOff ) ) { const QBitmap * mask = uncached( ( on ) ? ExIndicatorOn : ExIndicatorOff ) -> mask(); if ( mask ) { p->drawPixmap( x, y, *mask ); } else p->fillRect( x, y, w, h, QBrush( color1, SolidPattern ) ); } else QWindowsStyle::drawExclusiveIndicatorMask( p, x, y, w, h, on ); } void OThemeStyle::drawIndicatorMask( QPainter *p, int x, int y, int w, int h, int state ) { if ( isPixmap( ( state != QButton::Off ) ? IndicatorOn : IndicatorOff ) ) { const QBitmap * mask = uncached( ( state != QButton::Off ) ? IndicatorOn : IndicatorOff ) ->mask(); if ( mask ) p->drawPixmap( x, y, *mask ); else p->fillRect( x, y, w, h, QBrush( color1, SolidPattern ) ); } else QWindowsStyle::drawIndicatorMask( p, x, y, w, h, state ); } void OThemeStyle::drawSliderGroove( QPainter *p, int x, int y, int w, int h, const QColorGroup& g, QCOORD c, Orientation orient ) { if ( roundSlider() ) QWindowsStyle::drawSliderGroove( p, x, y, w, h, *colorGroup( g, SliderGroove ), c, orient ); else drawBaseButton( p, x, y, w, h, *colorGroup( g, SliderGroove ), true, false, SliderGroove ); } void OThemeStyle::drawSlider( QPainter *p, int x, int y, int w, int h, const QColorGroup &g, Orientation orient, bool tickAbove, bool tickBelow ) { if ( isPixmap( Slider ) ) { if ( orient == Qt::Horizontal ) p->drawPixmap( x, y + ( h - uncached( Slider ) ->height() ) / 2, *uncached( Slider ) ); else p->drawPixmap( x + ( w - uncached( Slider ) ->width() ) / 2, y, *uncached( Slider ) ); } else { QWindowsStyle::drawSlider( p, x, y, w, h, *colorGroup( g, Slider ), orient, tickAbove, tickBelow ); } } void OThemeStyle::drawSliderMask( QPainter *p, int x, int y, int w, int h, Orientation orient, bool tickAbove, bool tickBelow ) { // This is odd. If we fill in the entire region it still masks the slider // properly. I have no idea, this used to be different in Qt betas... if ( isPixmap( Slider ) ) p->fillRect( x, y, w, h, QBrush( color1, SolidPattern ) ); else QWindowsStyle::drawSliderMask( p, x, y, w, h, orient, tickAbove, tickBelow ); } int OThemeStyle::defaultFrameWidth() const { return ( frameWidth() ); } void OThemeStyle::getButtonShift( int &x, int &y ) { x = buttonXShift(); y = buttonYShift(); } int OThemeStyle::sliderLength() const { return ( sliderButtonLength() ); } void OThemeStyle::drawArrow( QPainter *p, Qt::ArrowType type, bool down, int x, int y, int w, int h, const QColorGroup &g, bool enabled, const QBrush * ) { // Handles pixmapped arrows. A little inefficent because you can specify // some as pixmaps and some as default types. WidgetType widget; switch ( type ) { case UpArrow: widget = enabled ? down ? SunkenArrowUp : ArrowUp : DisArrowUp; break; case DownArrow: widget = enabled ? down ? SunkenArrowDown : ArrowDown : DisArrowDown; break; case LeftArrow: widget = enabled ? down ? SunkenArrowLeft : ArrowLeft : DisArrowLeft; break; case RightArrow: default: widget = enabled ? down ? SunkenArrowRight : ArrowRight : DisArrowRight; break; } if ( isPixmap( widget ) ) { p->drawPixmap( x + ( w - uncached( widget ) ->width() ) / 2, y + ( h - uncached( widget ) ->height() ) / 2, *uncached( widget ) ); return ; } const QColorGroup *cg = colorGroup( g, widget ); // Standard arrow types if ( arrowType() == MotifArrow ) qDrawArrow( p, type, Qt::MotifStyle, down, x, y, w, h, *cg, enabled ); else if ( arrowType() == SmallArrow ) { QColorGroup tmp( *cg ); tmp.setBrush( QColorGroup::Button, QBrush( NoBrush ) ); QWindowsStyle::drawArrow( p, type, false, x, y, w, h, tmp, true ); } else { QPointArray a; int x2 = x + w - 1, y2 = y + h - 1; switch ( type ) { case Qt::UpArrow: a.setPoints( 4, x, y2, x2, y2, x + w / 2, y, x, y2 ); break; case Qt::DownArrow: a.setPoints( 4, x, y, x2, y, x + w / 2, y2, x, y ); break; case Qt::LeftArrow: a.setPoints( 4, x2, y, x2, y2, x, y + h / 2, x2, y ); break; default: a.setPoints( 4, x, y, x, y2, x2, y + h / 2, x, y ); break; } QBrush oldBrush = p->brush(); QPen oldPen = p->pen(); p->setBrush( cg->brush( QColorGroup::Shadow ) ); p->setPen( cg->shadow() ); p->drawPolygon( a ); p->setBrush( oldBrush ); p->setPen( oldPen ); } } /* This is where we draw the borders and highlights. The new round button * code is a pain in the arse. We don't want to be calculating arcs so * use a whole lotta QPointArray's ;-) The code is made a lot more complex * because you can have variable width border and highlights... * I may want to cache this if round buttons are used, but am concerned * about excessive cache misses. This is a memory/speed tradeoff that I * have to test. */ void OThemeStyle::drawShade( QPainter *p, int x, int y, int w, int h, const QColorGroup &g, bool sunken, bool rounded, int hWidth, int bWidth, ShadeStyle style ) { int i, sc, bc, x2, y2; QPen highPen, lowPen; if ( style == Motif ) { highPen.setColor( sunken ? g.dark() : g.light() ); lowPen.setColor( sunken ? g.light() : g.dark() ); } else { highPen.setColor( sunken ? g.shadow() : g.light() ); lowPen.setColor( sunken ? g.light() : g.shadow() ); } // Advanced round buttons if ( rounded && w > 19 && h > 19 ) { x2 = x + w - 1, y2 = y + h - 1; QPointArray bPntArray, hPntArray, lPntArray; QPointArray bLineArray, hLineArray, lLineArray; // borders for ( i = 0, bc = 0; i < bWidth; ++i ) { bPntArray.putPoints( bc, 24, x + 4, y + 1, x + 5, y + 1, x + 3, y + 2, x + 2, y + 3, x + 1, y + 4, x + 1, y + 5, x + 1, y2 - 5, x + 1, y2 - 4, x + 2, y2 - 3, x2 - 5, y + 1, x2 - 4, y + 1, x2 - 3, y + 2, x2 - 5, y2 - 1, x2 - 4, y2 - 1, x2 - 3, y2 - 2, x2 - 2, y2 - 3, x2 - 1, y2 - 5, x2 - 1, y2 - 4, x + 3, y2 - 2, x + 4, y2 - 1, x + 5, y2 - 1, x2 - 2, y + 3, x2 - 1, y + 4, x2 - 1, y + 5 ); bc += 24; // ellispe edges don't match exactly, so fill in blanks if ( i < bWidth - 1 || hWidth != 0 ) { bPntArray.putPoints( bc, 20, x + 6, y + 1, x + 4, y + 2, x + 3, y + 3, x + 2, y + 4, x + 1, y + 6, x2 - 6, y + 1, x2 - 4, y + 2, x2 - 3, y + 3, x + 2, y2 - 4, x + 1, y2 - 6, x2 - 6, y2 - 1, x2 - 4, y2 - 2, x2 - 3, y2 - 3, x2 - 2, y2 - 4, x2 - 1, y2 - 6, x + 6, y2 - 1, x + 4, y2 - 2, x + 3, y2 - 3, x2 - 1, y + 6, x2 - 2, y + 4 ); bc += 20; } bLineArray.putPoints( i * 8, 8, x + 6, y, x2 - 6, y, x, y + 6, x, y2 - 6, x + 6, y2, x2 - 6, y2, x2, y + 6, x2, y2 - 6 ); ++x, ++y; --x2, --y2; } // highlights for ( i = 0, sc = 0; i < hWidth; ++i ) { hPntArray.putPoints( sc, 12, x + 4, y + 1, x + 5, y + 1, // top left x + 3, y + 2, x + 2, y + 3, x + 1, y + 4, x + 1, y + 5, x + 1, y2 - 5, x + 1, y2 - 4, x + 2, y2 - 3, // half corners x2 - 5, y + 1, x2 - 4, y + 1, x2 - 3, y + 2 ); lPntArray.putPoints( sc, 12, x2 - 5, y2 - 1, x2 - 4, y2 - 1, // btm right x2 - 3, y2 - 2, x2 - 2, y2 - 3, x2 - 1, y2 - 5, x2 - 1, y2 - 4, x + 3, y2 - 2, x + 4, y2 - 1, x + 5, y2 - 1, //half corners x2 - 2, y + 3, x2 - 1, y + 4, x2 - 1, y + 5 ); sc += 12; if ( i < hWidth - 1 ) { hPntArray.putPoints( sc, 10, x + 6, y + 1, x + 4, y + 2, // top left x + 3, y + 3, x + 2, y + 4, x + 1, y + 6, x2 - 6, y + 1, x2 - 4, y + 2, // half corners x2 - 3, y + 3, x + 2, y2 - 4, x + 1, y2 - 6 ); lPntArray.putPoints( sc, 10, x2 - 6, y2 - 1, x2 - 4, y2 - 2, // btm right x2 - 3, y2 - 3, x2 - 2, y2 - 4, x2 - 1, y2 - 6, x + 6, y2 - 1, x + 4, y2 - 2, // half corners x + 3, y2 - 3, x2 - 1, y + 6, x2 - 2, y + 4 ); sc += 10; } hLineArray.putPoints( i * 4, 4, x + 6, y, x2 - 6, y, x, y + 6, x, y2 - 6 ); lLineArray.putPoints( i * 4, 4, x + 6, y2, x2 - 6, y2, x2, y + 6, x2, y2 - 6 ); ++x, ++y; --x2, --y2; } p->setPen( Qt::black ); p->drawPoints( bPntArray ); p->drawLineSegments( bLineArray ); p->setPen( highPen ); p->drawPoints( hPntArray ); p->drawLineSegments( hLineArray ); p->setPen( lowPen ); p->drawPoints( lPntArray ); p->drawLineSegments( lLineArray ); } // Rectangular buttons else { QPointArray highShade( hWidth * 4 ); QPointArray lowShade( hWidth * 4 ); p->setPen( g.shadow() ); for ( i = 0; i < bWidth && w > 2 && h > 2; ++i, ++x, ++y, w -= 2, h -= 2 ) p->drawRect( x, y , w, h ); if ( !hWidth ) return ; x2 = x + w - 1, y2 = y + h - 1; for ( i = 0; i < hWidth; ++i, ++x, ++y, --x2, --y2 ) { highShade.putPoints( i * 4, 4, x, y, x2, y, x, y, x, y2 ); lowShade.putPoints( i * 4, 4, x, y2, x2, y2, x2, y, x2, y2 ); } if ( style == Windows && hWidth > 1 ) { p->setPen( highPen ); p->drawLineSegments( highShade, 0, 2 ); p->setPen( lowPen ); p->drawLineSegments( lowShade, 0, 2 ); p->setPen( ( sunken ) ? g.dark() : g.mid() ); p->drawLineSegments( highShade, 4 ); p->setPen( ( sunken ) ? g.mid() : g.dark() ); p->drawLineSegments( lowShade, 4 ); } else { p->setPen( ( sunken ) ? g.dark() : g.light() ); p->drawLineSegments( highShade ); p->setPen( ( sunken ) ? g.light() : g.dark() ); p->drawLineSegments( lowShade ); } } } void OThemeStyle::drawPushButtonLabel( QPushButton *btn, QPainter *p ) { WidgetType widget = btn->isDown() || btn->isOn() ? PushButtonDown : PushButton; const QColorGroup *cg = colorGroup( btn->colorGroup(), widget ); int x, y, w, h; QRect r = btn->rect(); r.rect( &x, &y, &w, &h ); x += decoWidth( widget ); y += decoWidth( widget ); w -= decoWidth( widget ) * 2; h -= decoWidth( widget ) * 2; bool act = btn->isOn() || btn->isDown(); // If this is a button with an associated popup menu, draw an arrow first if ( btn->popup() ) { int dx = menuButtonIndicatorWidth( btn->height() ); QColorGroup g( btn->colorGroup() ); int xx = x + w - dx - 4; int yy = y - 3; int hh = h + 6; if ( !act ) { p->setPen( g.light() ); p->drawLine( xx, yy + 3, xx, yy + hh - 4 ); } else { p->setPen( g.button() ); p->drawLine( xx, yy + 4, xx, yy + hh - 4 ); } drawArrow( p, DownArrow, FALSE, x + w - dx - 2, y + 2, dx, h - 4, btn->colorGroup(), btn->isEnabled() ); w -= dx; } // Next, draw iconset, if any if ( btn->iconSet() && !btn->iconSet() ->isNull() ) { QIconSet::Mode mode = btn->isEnabled() ? QIconSet::Normal : QIconSet::Disabled; if ( mode == QIconSet::Normal && btn->hasFocus() ) mode = QIconSet::Active; QPixmap pixmap = btn->iconSet() ->pixmap( QIconSet::Small, mode ); int pixw = pixmap.width(); int pixh = pixmap.height(); p->drawPixmap( x + 6, y + h / 2 - pixh / 2, pixmap ); x += pixw + 8; w -= pixw + 8; } if ( widget == PushButtonDown ) { drawItem( p, x + buttonXShift(), y + buttonYShift(), w, h, AlignCenter | ShowPrefix, *cg, btn->isEnabled(), btn->pixmap(), btn->text(), -1, &cg->buttonText() ); } else { drawItem( p, x, y, w, h, AlignCenter | ShowPrefix, *cg, btn->isEnabled(), btn->pixmap(), btn->text(), -1, &cg->buttonText() ); } } int OThemeStyle::splitterWidth() const { return ( splitWidth() ); } void OThemeStyle::drawSplitter( QPainter *p, int x, int y, int w, int h, const QColorGroup &g, Orientation ) { drawBaseButton( p, x, y, w, h, *colorGroup( g, Splitter ), false, false, Splitter ); } void OThemeStyle::drawCheckMark( QPainter *p, int x, int y, int w, int h, const QColorGroup &g, bool act, bool dis ) { if ( isPixmap( CheckMark ) ) { if ( !dis ) p->drawPixmap( x + ( w - uncached( CheckMark ) ->width() ) / 2, y + ( h - uncached( CheckMark ) ->height() ) / 2, *uncached( CheckMark ) ); } else QWindowsStyle::drawCheckMark( p, x, y, w, h, *colorGroup( g, CheckMark ), act, dis ); } int OThemeStyle::popupMenuItemHeight( bool /*checkable*/, QMenuItem *mi, const QFontMetrics &fm ) { int h2, h = 0; int offset = QMAX( decoWidth( MenuItemDown ), decoWidth( MenuItem ) ) + 4; if ( mi->isSeparator() ) return ( 2 ); if ( mi->isChecked() ) h = isPixmap( CheckMark ) ? uncached( CheckMark ) ->height() + offset : offset + 16; if ( mi->pixmap() ) { h2 = mi->pixmap() ->height() + offset; h = h2 > h ? h2 : h; } if ( mi->iconSet() ) { h2 = mi->iconSet() -> pixmap( QIconSet::Small, QIconSet::Normal ).height() + offset; h = h2 > h ? h2 : h; } h2 = fm.height() + offset; h = h2 > h ? h2 : h; return ( h ); } void OThemeStyle::drawPopupMenuItem( QPainter* p, bool checkable, int maxpmw, int tab, QMenuItem* mi, const QPalette& pal, bool act, bool enabled, int x, int y, int w, int h ) { // I changed the following method to be based from Qt's instead of my own // wacky code. Works much better now :P (mosfet) static const int motifItemFrame = 2; // menu item frame width static const int motifItemHMargin = 5; // menu item hor text margin static const int motifItemVMargin = 4; // menu item ver text margin static const int motifArrowHMargin = 6; // arrow horizontal margin static const int windowsRightBorder = 12; // right border on windowsstatic const int windowsCheckMarkWidth = 12; // checkmarks width on windows bool dis = !enabled; const QColorGroup &g = dis ? *colorGroup( pal.normal(), MenuItem ) : *colorGroup( pal.normal(), MenuItemDown ); QColorGroup itemg = dis ? *colorGroup( pal.disabled(), MenuItem ) : act ? *colorGroup( pal.active(), MenuItemDown ) : *colorGroup( pal.normal(), MenuItem ); maxpmw = QMAX( maxpmw, 20 ); int checkcol = maxpmw; if ( mi && mi->isSeparator() ) { p->setPen( g.dark() ); p->drawLine( x, y, x + w, y ); p->setPen( g.light() ); p->drawLine( x, y + 1, x + w, y + 1 ); return ; } if ( act ) { drawBaseButton( p, x, y, w, h, g, true, false, MenuItemDown ); } else { drawShade( p, x, y, w, h, *colorGroup( g, MenuItem ), false, false, highlightWidth( MenuItem ), borderWidth( MenuItem ), shade() ); int dw = decoWidth( MenuItem ); - if ( !isPixmap( MenuItem ) ) + if ( !isPixmap( MenuItem ) ) { p->fillRect( x + dw, y + dw, w - dw * 2, h - dw * 2, colorGroup( g, MenuItem ) -> brush( QColorGroup::Background ) ); + } else { // process inactive item pixmaps as one large item p->drawTiledPixmap( x + dw, y + dw, w - dw * 2, h - dw * 2, *scalePixmap - // (w, p->window().height(), MenuItem), - ( w, p->clipRegion().boundingRect().height(), MenuItem ), + (w, ((QWidget *)p->device())->height(), MenuItem), + //( w, p->clipRegion().boundingRect().height(), MenuItem ), // cliping does not work in Qt/E x, y ); } if ( checkable && mi && mi->isChecked() ) { // draw 'pressed' border around checkable items // This is extremely important for items that have an iconset // because the checkmark isn't drawn in that case // An alternative would be superimposing the checkmark over // the iconset instead or not drawing the iconset at all. int mw = checkcol + motifItemFrame; drawShade( p, x, y, mw, h, g, true, false, highlightWidth( MenuItemDown ), borderWidth( MenuItemDown ), shade() ); } } if ( !mi ) return ; if ( mi->iconSet() ) { QIconSet::Mode mode = dis ? QIconSet::Disabled : QIconSet::Normal; if ( act && !dis ) mode = QIconSet::Active; QPixmap pixmap = mi->iconSet() ->pixmap( QIconSet::Small, mode ); int pixw = pixmap.width(); int pixh = pixmap.height(); QRect cr( x, y, checkcol, h ); QRect pmr( 0, 0, pixw, pixh ); pmr.moveCenter( cr.center() ); p->setPen( itemg.text() ); p->drawPixmap( pmr.topLeft(), pixmap ); } else if ( checkable ) { int mw = checkcol + motifItemFrame; int mh = h - 2 * motifItemFrame; if ( mi->isChecked() ) { drawCheckMark( p, x + motifItemFrame, y + motifItemFrame, mw, mh, itemg, act, dis ); } } p->setPen( colorGroup( g, act ? MenuItemDown : MenuItem ) ->text() ); QColor discol; if ( dis ) { discol = itemg.text(); p->setPen( discol ); } int xm = motifItemFrame + checkcol + motifItemHMargin; QString s = mi->text(); if ( !s.isNull() ) { int t = s.find( '\t' ); int m = motifItemVMargin; const int text_flags = AlignVCenter | ShowPrefix | DontClip | SingleLine; if ( t >= 0 ) { if ( dis && !act ) { p->setPen( g.light() ); p->drawText( x + w - tab - windowsRightBorder - motifItemHMargin - motifItemFrame + 1, y + m + 1, tab, h - 2 * m, text_flags, s.mid( t + 1 ) ); p->setPen( discol ); } p->drawText( x + w - tab - windowsRightBorder - motifItemHMargin - motifItemFrame, y + m, tab, h - 2 * m, text_flags, s.mid( t + 1 ) ); } if ( dis && !act ) { p->setPen( g.light() ); p->drawText( x + xm + 1, y + m + 1, w - xm + 1, h - 2 * m, text_flags, s, t ); p->setPen( discol ); } p->drawText( x + xm, y + m, w - xm - tab + 1, h - 2 * m, text_flags, s, t ); } else if ( mi->pixmap() ) { QPixmap * pixmap = mi->pixmap(); if ( pixmap->depth() == 1 ) p->setBackgroundMode( OpaqueMode ); p->drawPixmap( x + xm, y + motifItemFrame, *pixmap ); if ( pixmap->depth() == 1 ) p->setBackgroundMode( TransparentMode ); } if ( mi->popup() ) { int dim = ( h - 2 * motifItemFrame ) / 2; if ( act ) { if ( !dis ) discol = colorGroup( g, MenuItemDown ) ->text(); //discol = white; QColorGroup g2( discol, g.highlight(), white, white, dis ? discol : white, discol, white ); drawArrow( p, RightArrow, true, x + w - motifArrowHMargin - motifItemFrame - dim, y + h / 2 - dim / 2, dim, dim, g2, TRUE ); } else { drawArrow( p, RightArrow, false, x + w - motifArrowHMargin - motifItemFrame - dim, y + h / 2 - dim / 2, dim, dim, g, mi->isEnabled() ); } } } void OThemeStyle::drawFocusRect( QPainter *p, const QRect &r, const QColorGroup &g, const QColor *c, bool atBorder ) { p->setPen( g.dark() ); if ( !is3DFocus() ) QWindowsStyle::drawFocusRect( p, r, g, c, atBorder ); else { int i = focusOffset(); p->drawLine( r.x() + i, r.y() + 1 + i, r.x() + i, r.bottom() - 1 - i ); p->drawLine( r.x() + 1 + i, r.y() + i, r.right() - 1 - i, r.y() + i ); p->setPen( g.light() ); p->drawLine( r.right() - i, r.y() + 1 + i, r.right() - i, r.bottom() - 1 - i ); p->drawLine( r.x() + 1 + i, r.bottom() - i, r.right() - 1 - i, r.bottom() - i ); } } #if 0 void OThemeStyle::drawKMenuBar( QPainter *p, int x, int y, int w, int h, const QColorGroup &g, bool, QBrush * ) { drawBaseButton( p, x, y, w, h, *colorGroup( g, MenuBar ), false, false, MenuBar ); } void OThemeStyle::drawKMenuItem( QPainter *p, int x, int y, int w, int h, const QColorGroup &g, bool active, QMenuItem *mi, QBrush * ) { const QColorGroup * cg = colorGroup( g, active ? MenuBarItem : MenuBar ); QColor btext = cg->buttonText(); if ( active ) drawBaseButton( p, x, y, w, h, *cg, false, false, MenuBarItem ); //qDrawShadePanel(p, x, y, w, h, *cg, false, 1); drawItem( p, x, y, w, h, AlignCenter | ShowPrefix | DontClip | SingleLine, *cg, mi->isEnabled(), mi->pixmap(), mi->text(), -1, &btext ); ; } void OThemeStyle::drawKProgressBlock( QPainter *p, int x, int y, int w, int h, const QColorGroup &g, QBrush * ) { drawBaseButton( p, x, y, w, h, *colorGroup( g, ProgressBar ), false, false, ProgressBar ); } void OThemeStyle::getKProgressBackground( const QColorGroup &g, QBrush &bg ) { const QColorGroup * cg = colorGroup( g, ProgressBg ); bg.setColor( cg->color( QColorGroup::Background ) ); if ( isPixmap( ProgressBg ) ) bg.setPixmap( *uncached( ProgressBg ) ); } #endif void OThemeStyle::tabbarMetrics( const QTabBar* t, int& hframe, int& vframe, int& overlap ) { QCommonStyle::tabbarMetrics( t, hframe, vframe, overlap ); } void OThemeStyle::drawTab( QPainter* p, const QTabBar* tb, QTab* t , bool selected ) { WidgetType widget = selected ? ActiveTab : InactiveTab; const QColorGroup *cg = colorGroup( tb->colorGroup(), widget ); int i; int x = t->r.x(), y = t->r.y(); int x2 = t->r.right(), y2 = t->r.bottom(); int bWidth = borderWidth( widget ); int hWidth = highlightWidth( widget ); if ( tb->shape() == QTabBar::RoundedAbove ) { if ( !selected ) { p->fillRect( x, y, x2 - x + 1, 2, tb->palette().normal().brush( QColorGroup::Background ) ); y += 2; } p->setPen( cg->text() ); i = 0; if ( i < bWidth ) { p->drawLine( x, y + 1, x, y2 ); p->drawLine( x2, y + 1, x2, y2 ); p->drawLine( x + 1, y, x2 - 1, y ); if ( selected ? activeTabLine() : inactiveTabLine() ) { p->drawLine( x, y2, x2, y2 ); --y2; } ++i, ++x, ++y, --x2; } for ( ; i < bWidth; ++i, ++x, ++y, --x2 ) { p->drawLine( x, y, x, y2 ); p->drawLine( x2, y, x2, y2 ); p->drawLine( x, y, x2, y ); if ( selected ? activeTabLine() : inactiveTabLine() ) { p->drawLine( x, y2, x2, y2 ); --y2; } } i = 0; if ( i < hWidth && bWidth == 0 ) { p->setPen( cg->light() ); p->drawLine( x, y + 1, x, y2 ); p->drawLine( x + 1, y, x2 - 1, y ); p->setPen( cg->dark() ); p->drawLine( x2, y + 1, x2, y2 ); if ( selected ? activeTabLine() : inactiveTabLine() ) { p->drawLine( x, y2, x2, y2 ); --y2; } ++i, ++x, ++y, --x2; } for ( ; i < hWidth; ++i, ++x, ++y, --x2 ) { p->setPen( cg->light() ); p->drawLine( x, y, x, y2 ); p->drawLine( x, y, x2, y ); p->setPen( cg->dark() ); p->drawLine( x2, y + 1, x2, y2 ); if ( selected ? activeTabLine() : inactiveTabLine() ) { p->drawLine( x, y2, x2, y2 ); --y2; } } if ( isPixmap( widget ) ) p->drawTiledPixmap( x, y, x2 - x + 1, y2 - y + 1, *scalePixmap( x2 - x + 1, y2 - y + 1, widget ) ); else p->fillRect( x, y, x2 - x + 1, y2 - y + 1, cg->background() ); } else if ( tb->shape() == QTabBar::RoundedBelow ) { if ( !selected ) { p->fillRect( x, y2 - 2, x2 - x + 1, 2, tb->palette().normal().brush( QColorGroup::Background ) ); y2 -= 2; } p->setPen( cg->text() ); i = 0; if ( i < bWidth ) { p->drawLine( x, y, x, y2 - 1 ); p->drawLine( x2, y, x2, y2 - 1 ); p->drawLine( x + 1, y2, x2 - 1, y2 ); if ( selected ? activeTabLine() : inactiveTabLine() ) { p->drawLine( x, y, x2, y ); ++y; } } for ( ; i < bWidth; ++i, ++x, --x2, --y2 ) { p->drawLine( x, y, x, y2 ); p->drawLine( x2, y, x2, y2 ); p->drawLine( x, y2, x2, y2 ); if ( selected ? activeTabLine() : inactiveTabLine() ) { p->drawLine( x, y, x2, y ); ++y; } } i = 0; if ( i < hWidth && bWidth == 0 ) { p->setPen( cg->dark() ); p->drawLine( x + 1, y2, x2 - 1, y2 ); p->drawLine( x2, y, x2, y2 - 1 ); p->setPen( cg->light() ); p->drawLine( x, y, x, y2 - 1 ); if ( selected ? activeTabLine() : inactiveTabLine() ) { p->drawLine( x, y, x2, y ); ++y; } ++i, ++x, --x2, --y2; } for ( ; i < hWidth; ++i, ++x, --x2, --y2 ) { p->setPen( cg->dark() ); p->drawLine( x, y2, x2, y2 ); p->drawLine( x2, y, x2, y2 ); p->setPen( cg->light() ); p->drawLine( x, y, x, y2 ); if ( selected ? activeTabLine() : inactiveTabLine() ) { p->drawLine( x, y, x2, y ); ++y; } } if ( isPixmap( widget ) ) p->drawTiledPixmap( x, y, x2 - x + 1, y2 - y + 1, *scalePixmap( x2 - x + 1, y2 - y + 1, widget ) ); else p->fillRect( x, y, x2 - x + 1, y2 - y + 1, cg->background() ); } else QCommonStyle::drawTab( p, tb, t, selected ); } void OThemeStyle::drawTabMask( QPainter* p, const QTabBar* tb, QTab* t, bool selected ) { QRect r( t->r ); if ( tb->shape() == QTabBar::RoundedAbove ) { if ( !selected ) r.setTop( r.top() + 2 ); p->drawLine( r.left() + 1, r.top(), r.right() - 1, r.top() ); QBrush b( color1, SolidPattern ); p->fillRect( r.left(), r.top() + 1, r.width(), r.height() - 1, b ); } else if ( tb->shape() == QTabBar::RoundedBelow ) { if ( !selected ) r.setBottom( r.bottom() - 2 ); p->drawLine( r.left() + 1, r.bottom(), r.right() - 1, r.bottom() ); QBrush b( color1, SolidPattern ); p->fillRect( r.left(), r.top(), r.width(), r.height() - 1, b ); } else QCommonStyle::drawTabMask( p, tb, t, selected ); } //#include "kthemestyle.moc" |