author | sandman <sandman> | 2002-11-28 00:37:59 (UTC) |
---|---|---|
committer | sandman <sandman> | 2002-11-28 00:37:59 (UTC) |
commit | 0d508bf39ad43aa06c9cd395dd382d8e00dfbf3a (patch) (side-by-side diff) | |
tree | f4a225c3236b2608c1127e62750c4106e35bfd66 | |
parent | 57ad30fb514428e068142e31ee40aa1615291123 (diff) | |
download | opie-0d508bf39ad43aa06c9cd395dd382d8e00dfbf3a.zip opie-0d508bf39ad43aa06c9cd395dd382d8e00dfbf3a.tar.gz opie-0d508bf39ad43aa06c9cd395dd382d8e00dfbf3a.tar.bz2 |
Some checks for null pixmaps (qtmail seems to create a scrollbar with
width and height == -1 when you tap "New mailbox")
-rw-r--r-- | noncore/styles/theme/ogfxeffect.cpp | 6 | ||||
-rw-r--r-- | noncore/styles/theme/othemestyle.cpp | 6 |
2 files changed, 9 insertions, 3 deletions
diff --git a/noncore/styles/theme/ogfxeffect.cpp b/noncore/styles/theme/ogfxeffect.cpp index 2071a67..90b45fe 100644 --- a/noncore/styles/theme/ogfxeffect.cpp +++ b/noncore/styles/theme/ogfxeffect.cpp @@ -1,509 +1,511 @@ /* 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" #include <cstdlib> #include <cmath> //====================================================================== // // Gradient effects // //====================================================================== QPixmap& OGfxEffect::gradient(QPixmap &pixmap, const QColor &ca, const QColor &cb, GradientType eff, int ncols) { + if ( !pixmap. isNull ( )) { 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; 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()); if( eff == VerticalGradient || eff == HorizontalGradient ){ uint *p; uint rgb; register int rl = rca << 16; register int gl = gca << 16; register int bl = bca << 16; if( eff == VerticalGradient ) { int rcdelta = ((1<<16) / size.height()) * rDiff; int gcdelta = ((1<<16) / size.height()) * gDiff; int bcdelta = ((1<<16) / size.height()) * bDiff; for ( y = 0; y < size.height(); y++ ) { p = (uint *) image.scanLine(y); rl += rcdelta; gl += gcdelta; bl += bcdelta; rgb = qRgb( (rl>>16), (gl>>16), (bl>>16) ); for( x = 0; x < size.width(); x++ ) { *p = rgb; p++; } } } 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; *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++; } } } else { 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; } 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*/) { + if ( !pixmap. isNull ( )) { 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/othemestyle.cpp b/noncore/styles/theme/othemestyle.cpp index a820efb..98e7253 100644 --- a/noncore/styles/theme/othemestyle.cpp +++ b/noncore/styles/theme/othemestyle.cpp @@ -1,1060 +1,1064 @@ /* This file is part of the KDE libraries Copyright (C) 1999 Daniel M. Duley <mosfet@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "othemestyle.h" #include "othemebase.h" #include <qpe/qpeapplication.h> #include <qbitmap.h> #define INCLUDE_MENUITEM_DEF #include <qmenudata.h> #include <qpopupmenu.h> #include <qtabbar.h> #include <qglobal.h> #include <qprogressbar.h> #include <limits.h> #include <stdio.h> typedef void (QStyle::*QDrawMenuBarItemImpl) (QPainter *, int, int, int, int, QMenuItem *, QColorGroup &, bool, bool); QDrawMenuBarItemImpl qt_set_draw_menu_bar_impl(QDrawMenuBarItemImpl impl); /* !! HACK !! Beware * * TT forgot to make the QProgressBar widget styleable in Qt 2.x * So the only way to customize the drawing, is to intercept the * paint event - since we have to use protected functions, we need * to derive a "hack" class from QProgressBar and do the painting * in there. * * - sandman */ class HackProgressBar : public QProgressBar { public: HackProgressBar ( ); void paint ( QPaintEvent *event, OThemeStyle *style ) { QPainter p( this ); if ( !contentsRect().contains( event->rect() ) ) { p.save(); p.setClipRegion( event->region().intersect(frameRect()) ); drawFrame( &p); p.restore(); } if ( event->rect().intersects( contentsRect() )) { p.setClipRegion( event->region().intersect( contentsRect() ) ); int x, y, w, h; contentsRect ( ). rect ( &x, &y, &w, &h ); int prog = progress ( ); int total = totalSteps ( ); if ( prog < 0 ) prog = 0; if ( total <= 0 ) total = 1; int perc = prog * 100 / total; style-> drawProgressBar ( &p, x, y, w, h, colorGroup ( ), perc ); if ( progress ( ) >= 0 && totalSteps ( ) > 0 ) { QString pstr; pstr. sprintf ( "%d%%", 100 * progress()/totalSteps ()); p. setPen ( colorGroup().text());//g.highlightedText ( )); p. drawText (x,y,w-1,h-1,AlignCenter,pstr); } } } }; #define QCOORDARRLEN(x) sizeof(x)/(sizeof(QCOORD)*2) OThemeStyle::OThemeStyle( const QString &configFile ) : OThemeBase( configFile ) { setScrollBarExtent( getSBExtent(), getSBExtent() ); setButtonDefaultIndicatorWidth( 0 ); // We REALLY should support one, see drawPushButton() below! } OThemeStyle::~OThemeStyle() {} void OThemeStyle::polish( QApplication * /*app*/ ) { qt_set_draw_menu_bar_impl((QDrawMenuBarItemImpl) &OThemeStyle::drawMenuBarItem); } void OThemeStyle::polish( QPalette &p ) { oldPalette = p; QColor bg = oldPalette. color ( QPalette::Normal, QColorGroup::Background ); if ( bgcolor. isValid ( )) bg = bgcolor; if ( isColor ( Background )) bg = colorGroup ( oldPalette. active ( ), Background )-> background ( ); p = QPalette ( bg, bg ); if ( isPixmap( Background ) ) p. setBrush ( QColorGroup::Background, QBrush ( bg, *uncached ( Background ))); if ( fgcolor. isValid ( )) { p. setColor ( QColorGroup::Foreground, fgcolor ); p. setColor ( QColorGroup::ButtonText, fgcolor ); } if ( selfgcolor. isValid ( )) p. setColor ( QColorGroup::HighlightedText, selfgcolor ); if ( selbgcolor. isValid ( )) p. setColor ( QColorGroup::Highlight, selbgcolor ); if ( winfgcolor. isValid ( )) p. setColor ( QColorGroup::Text, winfgcolor ); if ( winbgcolor. isValid ( )) p. setColor ( QColorGroup::Base, winbgcolor ); } void OThemeStyle::unPolish( QApplication *app ) { qt_set_draw_menu_bar_impl ( 0 ); app->setPalette( oldPalette, true ); } void OThemeStyle::polish( QWidget *w ) { if ( !w->isTopLevel() ) { if ( w->inherits( "QGroupBox" ) || w->inherits( "QTabWidget" ) ) { w->setAutoMask( TRUE ); return ; } if ( w->inherits( "QLabel" ) || w->inherits( "QSlider" ) || w->inherits( "QButton" ) || w->inherits( "QProgressBar" ) ) { w->setBackgroundOrigin( QWidget::ParentOrigin ); } } if ( w->inherits( "QPopupMenu" ) ) { popupPalette = w->palette(); if ( isColor( MenuItem ) || isColor( MenuItemDown ) ) { QPalette newPal( w->palette() ); w->setPalettePropagation( QWidget::SamePalette ); if ( isColor( MenuItem ) ) { newPal.setNormal( *colorGroup( newPal.normal(), MenuItem ) ); newPal.setDisabled( *colorGroup( newPal.normal(), MenuItem ) ); } if ( isColor( MenuItemDown ) ) newPal.setActive( *colorGroup( newPal.active(), MenuItemDown ) ); w->setPalette( newPal ); } } else if ( w->inherits( "QCheckBox" ) ) { if ( isColor( IndicatorOff ) || isColor( IndicatorOn ) ) { QPalette newPal( w->palette() ); w->setPalettePropagation( QWidget::SamePalette ); if ( isColor( IndicatorOff ) ) { newPal.setNormal( *colorGroup( newPal.normal(), IndicatorOff ) ); newPal.setDisabled( *colorGroup( newPal.normal(), IndicatorOff ) ); } if ( isColor( IndicatorOn ) ) newPal.setActive( *colorGroup( newPal.active(), IndicatorOn ) ); w->setPalette( newPal ); } } else if ( w->inherits( "QRadioButton" ) ) { if ( isColor( ExIndicatorOff ) || isColor( ExIndicatorOn ) ) { QPalette newPal( w->palette() ); w->setPalettePropagation( QWidget::SamePalette ); if ( isColor( ExIndicatorOff ) ) { newPal.setNormal( *colorGroup( newPal.normal(), ExIndicatorOff ) ); newPal.setDisabled( *colorGroup( newPal.normal(), ExIndicatorOff ) ); } if ( isColor( ExIndicatorOn ) ) newPal.setActive( *colorGroup( newPal.active(), ExIndicatorOn ) ); w->setPalette( newPal ); } } else if ( w-> inherits ( "QProgressBar" ) ) { w-> installEventFilter ( this ); } } void OThemeStyle::unPolish( QWidget* w ) { if ( !w->isTopLevel() ) { if ( w->inherits( "QGroupBox" ) || w->inherits( "QTabWidget" ) ) { w->setAutoMask( FALSE ); return ; } if ( w->inherits( "QLabel" ) || w->inherits( "QSlider" ) || w->inherits( "QButton" ) || w->inherits( "QProgressBar" ) ) { w->setBackgroundOrigin( QWidget::WidgetOrigin ); } } if ( w->inherits( "QPopupMenu" ) ) w->unsetPalette(); else if ( w->inherits( "QCheckBox" ) ) w->unsetPalette(); else if ( w->inherits( "QRadioButton" ) ) w->unsetPalette(); else if ( w-> inherits ( "QProgressBar" ) ) w-> removeEventFilter ( this ); } bool OThemeStyle::eventFilter ( QObject *obj, QEvent *ev ) { // only QProgressBar so far if ( ev-> type ( ) == QEvent::Paint ) { HackProgressBar *pb = (HackProgressBar *) obj; pb-> paint ((QPaintEvent *) ev, this ); return true; } return false; } void OThemeStyle::drawBaseButton( QPainter *p, int x, int y, int w, int h, const QColorGroup &g, bool sunken, bool rounded, WidgetType type, const QBrush * ) { + if ( w <= 0 || h <= 0 ) + return; + int offset = borderPixmap( type ) ? 0 : decoWidth( type ); QPen oldPen = p->pen(); // handle reverse bevel here since it uses decowidth differently if ( gradientHint( type ) == GrReverseBevel ) { int i; bitBlt( p->device(), x, y, scalePixmap( w, h, type ), 0, 0, w, h, Qt::CopyROP, true ); p->setPen( g.text() ); for ( i = 0; i < borderWidth( type ); ++i, ++x, ++y, w -= 2, h -= 2 ) p->drawRect( x, y, w, h ); } // same with KDE style borders else if ( !borderPixmap( type ) && shade() == KDE ) { qDrawWinButton( p, x, y, w, h, g, sunken ); if ( isPixmap( type ) ) p->drawTiledPixmap( x + 4, y + 4, w - 6, h - 6, *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 ) ) + 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; |