summaryrefslogtreecommitdiff
authorsandman <sandman>2002-11-28 00:37:59 (UTC)
committer sandman <sandman>2002-11-28 00:37:59 (UTC)
commit0d508bf39ad43aa06c9cd395dd382d8e00dfbf3a (patch) (side-by-side diff)
treef4a225c3236b2608c1127e62750c4106e35bfd66
parent57ad30fb514428e068142e31ee40aa1615291123 (diff)
downloadopie-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")
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--noncore/styles/theme/ogfxeffect.cpp6
-rw-r--r--noncore/styles/theme/othemestyle.cpp6
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;