Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

flat.cpp

Go to the documentation of this file.
00001 /**********************************************************************
00002 ** Copyright (C) 2000-2002 Trolltech AS.  All rights reserved.
00003 **
00004 ** This file is part of the Qtopia Environment.
00005 **
00006 ** This file may be distributed and/or modified under the terms of the
00007 ** GNU General Public License version 2 as published by the Free Software
00008 ** Foundation and appearing in the file LICENSE.GPL included in the
00009 ** packaging of this file.
00010 **
00011 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00012 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00013 **
00014 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
00015 **
00016 ** Contact info@trolltech.com if any conditions of this licensing are
00017 ** not clear to you.
00018 **
00019 **********************************************************************/
00020 
00021 #include <qtopia/qpeapplication.h>
00022 #include <qpushbutton.h>
00023 #include <qtoolbutton.h>
00024 #include <qpainter.h>
00025 #include <qfontmetrics.h>
00026 #include <qpalette.h>
00027 #include <qdrawutil.h>
00028 #include <qscrollbar.h>
00029 #include <qbutton.h>
00030 #include <qframe.h>
00031 #include <qtabbar.h>
00032 #include <qspinbox.h>
00033 #include <qlineedit.h>
00034 #include <qmap.h>
00035 
00036 #define INCLUDE_MENUITEM_DEF
00037 #include <qmenudata.h>
00038 #include <qpopupmenu.h>
00039 
00040 #include "flat.h"
00041 
00042 #define QCOORDARRLEN(x) sizeof(x)/(sizeof(QCOORD)*2)
00043 
00044 class SpinBoxHack : public QSpinBox
00045 {
00046 public:
00047     void setFlatButtons( bool f ) {
00048         upButton()->setFlat( f );
00049         downButton()->setFlat( f );
00050     }
00051 };
00052 
00053 class FlatStylePrivate : public QObject
00054 {
00055     Q_OBJECT
00056 public:
00057     FlatStylePrivate() : QObject() {}
00058 
00059     bool eventFilter( QObject *o, QEvent *e ) {
00060         if ( e->type() == QEvent::ParentPaletteChange ) {
00061             if ( o->inherits( "QMenuBar" ) ) {
00062                 QWidget *w = (QWidget *)o;
00063                 if ( w->parentWidget() ) {
00064                     QPalette p = w->parentWidget()->palette();
00065                     QColorGroup a = p.active();
00066                     a.setColor( QColorGroup::Light, a.foreground() );
00067                     a.setColor( QColorGroup::Dark, a.foreground() );
00068                     p.setActive( a );
00069                     p.setInactive( a );
00070                     w->setPalette( p );
00071                 }
00072             } else if ( o->inherits( "QHeader" ) ) {
00073                 QWidget *w = (QWidget *)o;
00074                 if ( w->parentWidget() ) {
00075                     QPalette p = w->parentWidget()->palette();
00076                     QColorGroup a = p.active();
00077                     a.setColor( QColorGroup::Light, a.button() );
00078                     p.setActive( a );
00079                     p.setInactive( a );
00080                     w->setPalette( p );
00081                 }
00082             }
00083         }
00084         return FALSE;
00085     }
00086 
00087     QMap<QFrame *,int> frameStyles;
00088 };
00089 
00090 FlatStyle::FlatStyle() : revItem(FALSE), fillBtnBorder(FALSE)
00091 {
00092     setButtonMargin(3);
00093     setScrollBarExtent(13,13);
00094     setButtonDefaultIndicatorWidth(0);
00095     d = new FlatStylePrivate;
00096 }
00097 
00098 FlatStyle::~FlatStyle()
00099 {
00100     delete d;
00101 }
00102 
00103 int FlatStyle::buttonMargin() const
00104 {
00105     return 3;
00106 }
00107 
00108 QSize FlatStyle::scrollBarExtent() const
00109 {
00110     return QSize(13,13);
00111 }
00112 
00113 void FlatStyle::polish ( QPalette & )
00114 {
00115 }
00116 
00117 void FlatStyle::polish( QWidget *w )
00118 {
00119     if ( w->inherits( "QFrame" ) ) {
00120         QFrame *f = (QFrame *)w;
00121         if ( f->frameShape() == QFrame::HLine || f->frameShape() == QFrame::VLine )
00122             f->setFrameShadow( QFrame::Plain );
00123         else if ( f->frameShape() != QFrame::NoFrame )
00124             f->setFrameShape( QFrame::StyledPanel );
00125         f->setLineWidth( 1 );
00126     }
00127     if ( w->inherits( "QSpinBox" ) )
00128         ((SpinBoxHack*)w)->setFlatButtons( TRUE );
00129     if ( w->inherits( "QMenuBar" ) ) {
00130         // make selected item look flat
00131         QPalette p = w->palette();
00132         QColorGroup a = p.active();
00133         a.setColor( QColorGroup::Light, a.foreground() );
00134         a.setColor( QColorGroup::Dark, a.foreground() );
00135         p.setActive( a );
00136         p.setInactive( a );
00137         w->setPalette( p );
00138         w->installEventFilter( d );
00139     } else if ( w->inherits( "QHeader" ) ) {
00140         // make headers look flat
00141         QPalette p = w->palette();
00142         QColorGroup a = p.active();
00143         a.setColor( QColorGroup::Light, a.button() );
00144         p.setActive( a );
00145         p.setInactive( a );
00146         w->setPalette( p );
00147         w->installEventFilter( d );
00148     }
00149 }
00150 
00151 void FlatStyle::unPolish( QWidget *w )
00152 {
00153     if ( w->inherits("QFrame") ) {
00154         QFrame *f = (QFrame *)w;
00155         if ( f->frameShape() == QFrame::HLine || f->frameShape() == QFrame::VLine ) {
00156             f->setFrameShadow( QFrame::Sunken );
00157         } else if ( f->frameShape() != QFrame::NoFrame ) {
00158             f->setFrameShape( QFrame::StyledPanel );
00159             f->setLineWidth( 2 );
00160         }
00161     }
00162     if ( w->inherits("QSpinBox") )
00163         ((SpinBoxHack*)w)->setFlatButtons( FALSE );
00164     if ( w->inherits("QMenuBar") || w->inherits("QHeader") ) {
00165         w->unsetPalette();
00166         w->removeEventFilter( d );
00167     }
00168 }
00169 
00170 int FlatStyle::defaultFrameWidth() const
00171 {
00172     return 2;
00173 }
00174 
00175 void FlatStyle::drawItem( QPainter *p, int x, int y, int w, int h,
00176                     int flags, const QColorGroup &g, bool enabled,
00177                     const QPixmap *pixmap, const QString& text, int len,
00178                     const QColor* penColor )
00179 {
00180     QColor pc( penColor ? *penColor : g.foreground() );
00181     QColorGroup cg( g );
00182     if ( !enabled )
00183         cg.setColor( QColorGroup::Light, cg.background() );
00184     if ( revItem ) {
00185         pc = cg.button();
00186         revItem = FALSE;
00187     }
00188     QWindowsStyle::drawItem( p, x, y, w, h, flags, cg, enabled, pixmap, text, len, &pc );
00189 }
00190 
00191 void FlatStyle::drawPanel ( QPainter * p, int x, int y, int w, int h,
00192                             const QColorGroup &g, bool /*sunken*/, int lineWidth, const QBrush * fill )
00193 {
00194     if ( fill )
00195         p->setBrush( *fill );
00196     p->setPen( QPen(g.foreground(), lineWidth) );
00197     p->drawRect( x, y, w, h );
00198 }
00199 
00200 void FlatStyle::drawButton( QPainter *p, int x, int y, int w, int h,
00201                                 const QColorGroup &cg, bool /*sunken*/, const QBrush* fill )
00202 {
00203     QPen oldPen = p->pen();
00204 
00205     int x2 = x+w-1;
00206     int y2 = y+h-1;
00207 
00208     if ( fillBtnBorder && btnBg != cg.color(QColorGroup::Button) ) {
00209         p->setPen( btnBg );
00210         p->drawLine( x, y, x2, y );
00211         p->drawLine( x, y2, x2, y2 );
00212         p->drawLine( x, y+1, x, y2-1 );
00213         p->drawLine( x2, y+1, x2, y2-1 );
00214         p->fillRect( x+1, y+1, 3, 3, btnBg );
00215         p->fillRect( x+1, y2-3, 3, 3, btnBg );
00216         p->fillRect( x2-3, y2-3, 3, 3, btnBg );
00217         p->fillRect( x2-3, y+1, 3, 3, btnBg );
00218         p->fillRect( x+2, y+2, w-4, h-4, fill?(*fill):cg.brush(QColorGroup::Button) );
00219     } else {
00220         p->fillRect( x+1, y+1, w-2, h-2, fill?(*fill):cg.brush(QColorGroup::Button) );
00221     }
00222 
00223     if ( h >= 10 ) {
00224         x++; y++;
00225         x2--; y2--;
00226         w -= 2; h -= 2;
00227     }
00228 
00229     p->setPen( cg.foreground() );
00230 
00231     if ( h < 10 ) {
00232         p->setBrush( NoBrush );
00233         p->drawRect( x, y, w, h );
00234     } else {
00235         p->drawLine( x+3, y, x2-3, y );
00236         p->drawLine( x+3, y2, x2-3, y2 );
00237         p->drawLine( x, y+3, x, y2-3 );
00238         p->drawLine( x2, y+3, x2, y2-3 );
00239 
00240         p->drawLine( x+1, y+1, x+2, y+1 );
00241         p->drawPoint( x+1, y+2 );
00242         p->drawLine( x2-2, y+1, x2-1, y+1 );
00243         p->drawPoint( x2-1, y+2 );
00244 
00245         p->drawLine( x+1, y2-1, x+2, y2-1 );
00246         p->drawPoint( x+1, y2-2 );
00247         p->drawLine( x2-2, y2-1, x2-1, y2-1 );
00248         p->drawPoint( x2-1, y2-2 );
00249     }
00250 
00251     p->setPen( oldPen );
00252 }
00253 
00254 void FlatStyle::drawButtonMask ( QPainter * p, int x, int y, int w, int h )
00255 {
00256     x++; y++;
00257     x-=2; y-=2;
00258     p->fillRect( x, y, w, h, color1 );
00259 }
00260 
00261 void FlatStyle::drawBevelButton( QPainter *p, int x, int y, int w, int h,
00262                                 const QColorGroup &g, bool /*sunken*/, const QBrush* fill )
00263 {
00264     p->fillRect( x+1, y+1, w-2, h-2, fill?(*fill):g.brush(QColorGroup::Button) );
00265     p->setPen( g.foreground() );
00266     p->setBrush( NoBrush );
00267     p->drawRect( x, y, w, h );
00268 }
00269 
00270 void FlatStyle::drawToolButton( QPainter *p, int x, int y, int w, int h,
00271                                 const QColorGroup &g, bool sunken, const QBrush* fill )
00272 {
00273     if ( p->device()->devType() == QInternal::Widget ) {
00274         QWidget *w = (QWidget *)p->device();
00275         if ( w->isA("QToolButton") ) {
00276             QToolButton *btn = (QToolButton *)w;
00277             if ( btn->parentWidget() ) {
00278                 btnBg = btn->parentWidget()->backgroundColor();
00279                 fillBtnBorder = TRUE;
00280             }
00281         }
00282     }
00283     QBrush fb( fill ? *fill : g.button() );
00284     if ( sunken && fb == g.brush( QColorGroup::Button ) ) {
00285         fb = g.buttonText();
00286         revItem = TRUE; // ugh
00287     }
00288     drawButton( p, x, y, w, h, g, sunken, &fb );
00289     fillBtnBorder = FALSE;
00290 }
00291 
00292 void FlatStyle::drawPushButton( QPushButton *btn, QPainter *p )
00293 {
00294     QColorGroup g = btn->colorGroup();
00295     int x1, y1, x2, y2;
00296 
00297     btn->rect().coords( &x1, &y1, &x2, &y2 );   // get coordinates
00298 
00299     p->setPen( g.foreground() );
00300     p->setBrush( QBrush(g.button(),NoBrush) );
00301 
00302 //    int diw = buttonDefaultIndicatorWidth();
00303     /*
00304     if ( btn->isDefault() || btn->autoDefault() ) {
00305         if ( btn->isDefault() ) {
00306             p->setPen( g.shadow() );
00307             p->drawRect( x1, y1, x2-x1+1, y2-y1+1 );
00308         }
00309         x1 += diw;
00310         y1 += diw;
00311         x2 -= diw;
00312         y2 -= diw;
00313     }
00314     */
00315 
00316     if ( btn->parentWidget() ) {
00317         btnBg = btn->parentWidget()->backgroundColor();
00318         fillBtnBorder = TRUE;
00319     }
00320 
00321     bool clearButton = TRUE;
00322     if ( btn->isDown() ) {
00323         drawButton( p, x1, y1, x2-x1+1, y2-y1+1, g, TRUE,
00324                 &g.brush( QColorGroup::Text ) );
00325     } else {
00326         if ( btn->isToggleButton() && btn->isOn() && btn->isEnabled() ) {
00327             QBrush fill(g.light(), Dense4Pattern );
00328             drawButton( p, x1, y1, x2-x1+1, y2-y1+1, g, TRUE, &fill );
00329             clearButton = FALSE;
00330         } else {
00331             if ( !btn->isFlat() )
00332                 drawButton( p, x1, y1, x2-x1+1, y2-y1+1, g, btn->isOn(),
00333                         &g.brush( QColorGroup::Button ) );
00334         }
00335     }
00336     /*
00337     if ( clearButton ) {
00338         if (btn->isDown())
00339             p->setBrushOrigin(p->brushOrigin() + QPoint(1,1));
00340         p->fillRect( x1+2, y1+2, x2-x1-3, y2-y1-3,
00341                      g.brush( QColorGroup::Button ) );
00342         if (btn->isDown())
00343             p->setBrushOrigin(p->brushOrigin() - QPoint(1,1));
00344     }
00345     */
00346 
00347     fillBtnBorder = FALSE;
00348     if ( p->brush().style() != NoBrush )
00349         p->setBrush( NoBrush );
00350 }
00351 
00352 void FlatStyle::drawPushButtonLabel( QPushButton *btn, QPainter *p )
00353 {
00354     QRect r = pushButtonContentsRect( btn );
00355     int x, y, w, h;
00356     r.rect( &x, &y, &w, &h );
00357     QColorGroup cg = btn->colorGroup();
00358     if ( btn->isToggleButton() && btn->isOn() && btn->isEnabled() && !btn->isDown() )
00359         cg.setColor( QColorGroup::ButtonText, btn->colorGroup().text() );
00360     else if ( btn->isDown() || btn->isOn() )
00361         cg.setColor( QColorGroup::ButtonText, btn->colorGroup().button() );
00362     if ( btn->isMenuButton() ) {
00363         int dx = menuButtonIndicatorWidth( btn->height() );
00364         drawArrow( p, DownArrow, FALSE,
00365                 x+w-dx, y+2, dx-4, h-4,
00366                 cg,
00367                 btn->isEnabled() );
00368         w -= dx;
00369     }
00370 
00371     if ( btn->iconSet() && !btn->iconSet()->isNull() ) {
00372         QIconSet::Mode mode = btn->isEnabled()
00373             ? QIconSet::Normal : QIconSet::Disabled;
00374         if ( mode == QIconSet::Normal && btn->hasFocus() )
00375             mode = QIconSet::Active;
00376         QPixmap pixmap = btn->iconSet()->pixmap( QIconSet::Automatic, mode );
00377         int pixw = pixmap.width();
00378         int pixh = pixmap.height();
00379         p->drawPixmap( x+2, y+h/2-pixh/2, pixmap );
00380         x += pixw + 4;
00381         w -= pixw + 4;
00382     }
00383     drawItem( p, x, y, w, h,
00384             AlignCenter | ShowPrefix,
00385             cg, btn->isEnabled(),
00386             btn->pixmap(), btn->text(), -1, &cg.buttonText() );
00387 
00388 }
00389 
00390 QRect FlatStyle::comboButtonRect( int x, int y, int w, int h)
00391 {
00392     return QRect(x+2, y+2, w-4-13, h-4);
00393 }
00394 
00395 
00396 QRect FlatStyle::comboButtonFocusRect( int x, int y, int w, int h)
00397 {
00398     return QRect(x+2, y+2, w-4-14, h-4);
00399 }
00400 
00401 void FlatStyle::drawComboButton( QPainter *p, int x, int y, int w, int h,
00402                                      const QColorGroup &g, bool sunken,
00403                                      bool /*editable*/,
00404                                      bool enabled,
00405                                      const QBrush * /*fill*/ )
00406 {
00407     x++; y++;
00408     w-=2; h-=2;
00409     p->setPen( g.foreground() );
00410     p->setBrush( QBrush(NoBrush) );
00411     p->drawRect( x, y, w, h );
00412     p->setPen( g.background() );
00413     p->drawRect( x+1, y+1, w-14, h-2 );
00414     p->fillRect( x+2, y+2, w-16, h-4, g.brush( QColorGroup::Base ) );
00415     QColorGroup cg( g );
00416     if ( sunken ) {
00417         cg.setColor( QColorGroup::ButtonText, g.button() );
00418         cg.setColor( QColorGroup::Button, g.buttonText() );
00419     }
00420     drawArrow( p, QStyle::DownArrow, FALSE,
00421                x+w-13, y+1, 12, h-2, cg, enabled,
00422                &cg.brush( QColorGroup::Button ) );
00423 
00424 }
00425 
00426 
00427 void FlatStyle::drawExclusiveIndicator ( QPainter * p, int x, int y, int w,
00428         int h, const QColorGroup &cg, bool on, bool down, bool enabled )
00429 {
00430     static const QCOORD pts1[] = {              // dark lines
00431         1,9, 1,8, 0,7, 0,4, 1,3, 1,2, 2,1, 3,1, 4,0, 7,0, 8,1, 9,1 };
00432     static const QCOORD pts4[] = {              // white lines
00433         2,10, 3,10, 4,11, 7,11, 8,10, 9,10, 10,9, 10,8, 11,7,
00434         11,4, 10,3, 10,2 };
00435     static const QCOORD pts5[] = {              // inner fill
00436         4,2, 7,2, 9,4, 9,7, 7,9, 4,9, 2,7, 2,4 };
00437 
00438     p->eraseRect( x, y, w, h );
00439     QPointArray a( QCOORDARRLEN(pts1), pts4 );
00440     a.translate( x, y );
00441     p->setPen( cg.foreground() );
00442     p->drawPolyline( a );
00443     a.setPoints( QCOORDARRLEN(pts4), pts1 );
00444     a.translate( x, y );
00445     p->setPen( cg.foreground() );
00446     p->drawPolyline( a );
00447     a.setPoints( QCOORDARRLEN(pts5), pts5 );
00448     a.translate( x, y );
00449     QColor fillColor = ( down || !enabled ) ? cg.button() : cg.base();
00450     p->setPen( fillColor );
00451     p->setBrush( fillColor  ) ;
00452     p->drawPolygon( a );
00453     if ( on ) {
00454         p->setPen( NoPen );
00455         p->setBrush( cg.text() );
00456         p->drawRect( x+5, y+4, 2, 4 );
00457         p->drawRect( x+4, y+5, 4, 2 );
00458     }
00459 }
00460 
00461 void FlatStyle::drawIndicator ( QPainter * p, int x, int y, int w, int h,
00462         const QColorGroup &cg, int state, bool down, bool enabled )
00463 {
00464     QColorGroup mycg( cg );
00465     mycg.setBrush( QColorGroup::Button, QBrush() );
00466     QBrush fill;
00467     drawButton( p, x, y, w, h, mycg, TRUE, 0 );
00468     if ( down )
00469         fill = cg.brush( QColorGroup::Button );
00470     else
00471         fill = cg.brush( enabled ? QColorGroup::Base : QColorGroup::Background );
00472     mycg.setBrush( QColorGroup::Button, fill );
00473     p->fillRect( x+1, y+1, w-2, h-2, fill );
00474     if ( state != QButton::Off ) {
00475         QPointArray a( 7*2 );
00476         int i, xx, yy;
00477         xx = x+3;
00478         yy = y+5;
00479         for ( i=0; i<3; i++ ) {
00480             a.setPoint( 2*i,   xx, yy );
00481             a.setPoint( 2*i+1, xx, yy+2 );
00482             xx++; yy++;
00483         }
00484         yy -= 2;
00485         for ( i=3; i<7; i++ ) {
00486             a.setPoint( 2*i,   xx, yy );
00487             a.setPoint( 2*i+1, xx, yy+2 );
00488             xx++; yy--;
00489         }
00490         if ( state == QButton::NoChange ) {
00491             p->setPen( mycg.dark() );
00492         } else {
00493             p->setPen( mycg.text() );
00494         }
00495         p->drawLineSegments( a );
00496     }
00497 }
00498 
00499 #define HORIZONTAL      (sb->orientation() == QScrollBar::Horizontal)
00500 #define VERTICAL        !HORIZONTAL
00501 #define MOTIF_BORDER    2
00502 #define SLIDER_MIN      9 // ### motif says 6 but that's too small
00503 
00506 void FlatStyle::scrollBarMetrics( const QScrollBar* sb, int &sliderMin, int &sliderMax, int &sliderLength, int& buttonDim )
00507 {
00508     int maxLength;
00509     int length = HORIZONTAL ? sb->width()  : sb->height();
00510     int extent = HORIZONTAL ? sb->height() : sb->width();
00511 
00512     if ( length > (extent - 1)*2 )
00513         buttonDim = extent;
00514     else
00515         buttonDim = length/2 - 1;
00516 
00517     sliderMin = 0;
00518     maxLength  = length - buttonDim*2 + 2;
00519 
00520      if ( sb->maxValue() == sb->minValue() ) {
00521         sliderLength = maxLength;
00522      } else {
00523         sliderLength = (sb->pageStep()*maxLength)/
00524                         (sb->maxValue()-sb->minValue()+sb->pageStep());
00525         uint range = sb->maxValue()-sb->minValue();
00526         if ( sliderLength < SLIDER_MIN || range > INT_MAX/2 )
00527             sliderLength = SLIDER_MIN;
00528         if ( sliderLength > maxLength )
00529             sliderLength = maxLength;
00530      }
00531 
00532     sliderMax = sliderMin + maxLength - sliderLength;
00533 }
00534 
00537 QStyle::ScrollControl FlatStyle::scrollBarPointOver( const QScrollBar* sb, int sliderStart, const QPoint& p )
00538 {
00539     if ( !sb->rect().contains( p ) )
00540         return NoScroll;
00541     int sliderMin, sliderMax, sliderLength, buttonDim, pos;
00542     scrollBarMetrics( sb, sliderMin, sliderMax, sliderLength, buttonDim );
00543 
00544     if (sb->orientation() == QScrollBar::Horizontal)
00545         pos = p.x();
00546     else
00547         pos = p.y();
00548 
00549     if (pos < sliderStart)
00550         return SubPage;
00551     if (pos < sliderStart + sliderLength)
00552         return Slider;
00553     if (pos < sliderMax + sliderLength)
00554         return AddPage;
00555     if (pos < sliderMax + sliderLength + buttonDim)
00556         return SubLine;
00557     return AddLine;
00558 }
00559 
00562 void FlatStyle::drawScrollBarControls( QPainter* p, const QScrollBar* sb, int sliderStart, uint controls, uint activeControl )
00563 {
00564 #define ADD_LINE_ACTIVE ( activeControl == AddLine )
00565 #define SUB_LINE_ACTIVE ( activeControl == SubLine )
00566     QColorGroup g  = sb->colorGroup();
00567 
00568     int sliderMin, sliderMax, sliderLength, buttonDim;
00569     scrollBarMetrics( sb, sliderMin, sliderMax, sliderLength, buttonDim );
00570 
00571     if ( controls == (AddLine | SubLine | AddPage | SubPage | Slider | First | Last ) ) {
00572         p->setPen( g.foreground() );
00573         p->setBrush( g.brush( QColorGroup::Mid ) );
00574         p->drawRect( 0, 0, sb->width(), sb->height() );
00575     }
00576 
00577     if (sliderStart > sliderMax) { // sanity check
00578         sliderStart = sliderMax;
00579     }
00580 
00581     int dimB = buttonDim;
00582     QRect addB;
00583     QRect subB;
00584     QRect addPageR;
00585     QRect subPageR;
00586     QRect sliderR;
00587     int addX, addY, subX, subY;
00588     int length = HORIZONTAL ? sb->width()  : sb->height();
00589     int extent = HORIZONTAL ? sb->height() : sb->width();
00590 
00591     if ( HORIZONTAL ) {
00592         subY = addY = ( extent - dimB ) / 2;
00593         subX = length - dimB - dimB + 1;
00594         addX = length - dimB;
00595     } else {
00596         subX = addX = ( extent - dimB ) / 2;
00597         subY = length - dimB - dimB + 1;
00598         addY = length - dimB;
00599     }
00600 
00601     int sliderEnd = sliderStart + sliderLength;
00602     int sliderW = extent;
00603     if ( HORIZONTAL ) {
00604         subB.setRect( subX,subY,dimB,dimB );
00605         addB.setRect( addX,addY,dimB,dimB );
00606         subPageR.setRect( 0, 0, sliderStart+1, sliderW );
00607         addPageR.setRect( sliderEnd-1, 0, subX - sliderEnd+2, sliderW );
00608         sliderR .setRect( sliderStart, 0, sliderLength, sliderW );
00609 
00610     } else {
00611         subB.setRect( subX,subY,dimB,dimB );
00612         addB.setRect( addX,addY,dimB,dimB );
00613         subPageR.setRect( 0, 0, sliderW, sliderStart+1 );
00614         addPageR.setRect( 0, sliderEnd-1, sliderW, subY - sliderEnd+2 );
00615         sliderR .setRect( 0, sliderStart, sliderW, sliderLength );
00616     }
00617 
00618     bool maxedOut = (sb->maxValue() == sb->minValue());
00619     p->setPen( g.foreground() );
00620     if ( controls & AddLine ) {
00621         p->setBrush( ADD_LINE_ACTIVE ? g.foreground() : g.button() );
00622         p->drawRect( addB.x(), addB.y(), addB.width(), addB.height() );
00623         p->setPen( ADD_LINE_ACTIVE ? g.button() : g.foreground() );
00624         QColorGroup cg( g );
00625         if ( maxedOut )
00626             cg.setColor( QColorGroup::ButtonText, g.mid() );
00627         else if ( ADD_LINE_ACTIVE )
00628             cg.setColor( QColorGroup::ButtonText, g.button() );
00629         int xo = VERTICAL ? 1 : 0;
00630         drawArrow( p, VERTICAL ? DownArrow : RightArrow, FALSE,
00631                    addB.x()+2+xo, addB.y()+2, addB.width()-4-xo, addB.height()-4,
00632                    cg, TRUE, &p->brush() );
00633     }
00634     if ( controls & SubLine ) {
00635         p->setBrush( SUB_LINE_ACTIVE ? g.foreground() : g.button() );
00636         p->drawRect( subB.x(), subB.y(), subB.width(), subB.height() );
00637         p->setPen( SUB_LINE_ACTIVE ? g.button() : g.foreground() );
00638         QColorGroup cg( g );
00639         if ( maxedOut )
00640             cg.setColor( QColorGroup::ButtonText, g.mid() );
00641         else if ( SUB_LINE_ACTIVE )
00642             cg.setColor( QColorGroup::ButtonText, g.button() );
00643         int xo = VERTICAL ? 1 : 0;
00644         drawArrow( p, VERTICAL ? UpArrow : LeftArrow, FALSE,
00645                    subB.x()+2+xo, subB.y()+2, subB.width()-4-xo, subB.height()-4,
00646                    cg, TRUE, &p->brush() );
00647     }
00648 
00649 
00650     p->setPen( g.foreground() );
00651     p->setBrush( g.brush( QColorGroup::Mid ) );
00652     if ( controls & SubPage )
00653         p->drawRect( subPageR.x(), subPageR.y(), subPageR.width(), subPageR.height() );
00654     if ( controls & AddPage && addPageR.y() < addPageR.bottom() &&
00655          addPageR.x() < addPageR.right() )
00656         p->drawRect( addPageR.x(), addPageR.y(), addPageR.width(), addPageR.height() );
00657     if ( controls & Slider ) {
00658         QPoint bo = p->brushOrigin();
00659         p->setBrushOrigin(sliderR.topLeft());
00660         p->setPen( g.foreground() );
00661         p->setBrush( g.button() );
00662         p->drawRect( sliderR.x(), sliderR.y(), sliderR.width(), sliderR.height() );
00663         p->setBrushOrigin(bo);
00664         QColorGroup cg( g );
00665         if ( maxedOut )
00666             cg.setColor( QColorGroup::ButtonText, g.mid() );
00667         drawRiffles( p, sliderR.x(), sliderR.y(),
00668                      sliderR.width(), sliderR.height(), cg, HORIZONTAL );
00669     }
00670 
00671     // ### perhaps this should not be able to accept focus if maxedOut?
00672     if ( sb->hasFocus() && (controls & Slider) )
00673         p->drawWinFocusRect( sliderR.x()+2, sliderR.y()+2,
00674                              sliderR.width()-5, sliderR.height()-5,
00675                              sb->backgroundColor() );
00676 
00677 }
00678 
00679 void FlatStyle::drawRiffles( QPainter* p,  int x, int y, int w, int h,
00680                       const QColorGroup &g, bool horizontal )
00681 {
00682     if (!horizontal) {
00683         if (h > 20) {
00684             y += (h-20)/2 ;
00685             h = 20;
00686         }
00687         if (h > 12) {
00688             int n = 3;
00689             int my = y+h/2-2;
00690             int i ;
00691             p->setPen(g.buttonText());
00692             for (i=0; i<n; i++) {
00693                 p->drawLine(x+4, my+3*i, x+w-5, my+3*i);
00694             }
00695         }
00696     } else {
00697         if (w > 20) {
00698             x += (w-20)/2 ;
00699             w = 20;
00700         }
00701         if (w > 12) {
00702             int n = 3;
00703             int mx = x+w/2-4;
00704             int i ;
00705             p->setPen(g.buttonText());
00706             for (i=0; i<n; i++) {
00707                 p->drawLine(mx+3*i, y+4, mx + 3*i, y+h-5);
00708             }
00709         }
00710     }
00711 }
00712 
00713 int FlatStyle::sliderLength() const
00714 {
00715     return 12;
00716 }
00717 
00718 void FlatStyle::drawSlider( QPainter *p, int x, int y, int w, int h,
00719         const QColorGroup &g, Orientation o, bool tickAbove, bool tickBelow )
00720 {
00721     int a = tickAbove ? 3 : 0;
00722     int b = tickBelow ? 3 : 0;
00723 
00724     p->setPen( g.foreground() );
00725     p->setBrush( g.button() );
00726     if ( o == Horizontal ) {
00727         p->drawRect( x, y+a, w, h-a-b );
00728         int xp = x + w/2;
00729         p->drawLine( xp-1, y+a+3, xp-1, y+h-b-4 );
00730         p->drawLine( xp, y+a+3, xp, y+h-b-4 );
00731     } else {
00732         p->drawRect( x+a, y, w-a-b, h );
00733         int yp = y + h/2;
00734         p->drawLine( x+a+3, yp-1, x+w-b-4, yp-1 );
00735         p->drawLine( x+a+3, yp, x+w-b-4, yp );
00736     }
00737 }
00738 
00739 void FlatStyle::drawSliderMask ( QPainter * p, int x, int y, int w, int h,
00740         Orientation o, bool tickAbove, bool tickBelow )
00741 {
00742     int a = tickAbove ? 3 : 0;
00743     int b = tickBelow ? 3 : 0;
00744     if ( o == Horizontal )
00745         p->fillRect( x, y+a, w, h-a-b, color1 );
00746     else
00747         p->fillRect( x+a, y, w-a-b, h, color1 );
00748 }
00749 
00752 void FlatStyle::drawSliderGrooveMask( QPainter *p,
00753                                         int x, int y, int w, int h,
00754                                         const QColorGroup& , QCOORD c,
00755                                         Orientation orient )
00756 {
00757     if ( orient == Horizontal )
00758         p->fillRect( x, y + c - 2,  w, 4, color1 );
00759     else
00760         p->fillRect( x + c - 2, y, 4, h, color1 );
00761 }
00762 
00763 void FlatStyle::drawSliderGroove( QPainter *p, int x, int y, int w, int h, const QColorGroup &g, QCOORD c, Orientation orient )
00764 {
00765     if ( orient == Horizontal )
00766         p->fillRect( x, y + c - 2,  w, 4, g.foreground() );
00767     else
00768         p->fillRect( x + c - 2, y, 4, h, g.foreground() );
00769 }
00770 
00771 void FlatStyle::drawTab( QPainter *p, const QTabBar *tb, QTab *t, bool selected )
00772 {
00773     QRect r( t->rect() );
00774     if ( tb->shape()  == QTabBar::RoundedAbove ) {
00775         p->setPen( tb->colorGroup().foreground() );
00776         p->drawLine( r.left(), r.bottom(), r.right(), r.bottom() );
00777         if ( r.left() == 0 )
00778             p->drawPoint( tb->rect().bottomLeft() );
00779         else
00780             p->drawLine( r.left(), r.bottom(), r.right(), r.bottom() );
00781 
00782         if ( selected ) {
00783             p->setPen( tb->colorGroup().background() );
00784             p->drawLine( r.left()+2, r.top()+1, r.right()-2, r.top()+1 );
00785             p->fillRect( QRect( r.left()+1, r.top()+2, r.width()-2, r.height()-2),
00786                          tb->colorGroup().brush( QColorGroup::Background ));
00787         } else {
00788             r.setRect( r.left() + 2, r.top() + 2,
00789                        r.width() - 4, r.height() - 2 );
00790             p->setPen( tb->colorGroup().button() );
00791             p->drawLine( r.left()+2, r.top()+1, r.right()-2, r.top()+1 );
00792             p->fillRect( QRect( r.left()+1, r.top()+2, r.width()-2, r.height()-3),
00793                          tb->colorGroup().brush( QColorGroup::Button ));
00794         }
00795 
00796         p->setPen( tb->colorGroup().foreground() );
00797         p->drawLine( r.left(), r.bottom()-1, r.left(), r.top() + 2 );
00798         p->drawPoint( r.left()+1, r.top() + 1 );
00799         p->drawLine( r.left()+2, r.top(),
00800                      r.right() - 2, r.top() );
00801 
00802         p->drawPoint( r.right() - 1, r.top() + 1 );
00803         p->drawLine( r.right(), r.top() + 2, r.right(), r.bottom() - 1);
00804     } else if ( tb->shape() == QTabBar::RoundedBelow ) {
00805         if ( selected ) {
00806             p->setPen( tb->colorGroup().background() );
00807             p->drawLine( r.left()+2, r.bottom()-1, r.right()-2, r.bottom()-1 );
00808             p->fillRect( QRect( r.left()+1, r.top(), r.width()-2, r.height()-2),
00809                          tb->palette().normal().brush( QColorGroup::Background ));
00810         } else {
00811             p->setPen( tb->colorGroup().foreground() );
00812             p->drawLine( r.left(), r.top(),
00813                          r.right(), r.top() );
00814             r.setRect( r.left() + 2, r.top(),
00815                        r.width() - 4, r.height() - 2 );
00816             p->setPen( tb->colorGroup().button() );
00817             p->drawLine( r.left()+2, r.bottom()-1, r.right()-2, r.bottom()-1 );
00818             p->fillRect( QRect( r.left()+1, r.top()+1, r.width()-2, r.height()-3),
00819                          tb->palette().normal().brush( QColorGroup::Button ));
00820         }
00821 
00822         p->setPen( tb->colorGroup().foreground() );
00823         p->drawLine( r.right(), r.top(),
00824                      r.right(), r.bottom() - 2 );
00825         p->drawPoint( r.right() - 1, r.bottom() - 1 );
00826         p->drawLine( r.right() - 2, r.bottom(),
00827                      r.left() + 2, r.bottom() );
00828 
00829         p->drawLine( r.left(), r.top()+1,
00830                      r.left(), r.bottom() - 2 );
00831         p->drawPoint( r.left() + 1, r.bottom() - 1 );
00832         if ( r.left() == 0 )
00833             p->drawPoint( tb->rect().topLeft() );
00834 
00835     } else {
00836         QCommonStyle::drawTab( p, tb, t, selected );
00837     }
00838 }
00839 
00840 static const int motifItemFrame         = 0;    // menu item frame width
00841 static const int motifSepHeight         = 2;    // separator item height
00842 static const int motifItemHMargin       = 1;    // menu item hor text margin
00843 static const int motifItemVMargin       = 2;    // menu item ver text margin
00844 static const int motifArrowHMargin      = 0;    // arrow horizontal margin
00845 static const int motifTabSpacing        = 12;   // space between text and tab
00846 static const int motifCheckMarkHMargin  = 1;    // horiz. margins of check mark
00847 static const int windowsRightBorder     = 8;    // right border on windows
00848 static const int windowsCheckMarkWidth  = 2;    // checkmarks width on windows
00849 
00850 void FlatStyle::polishPopupMenu ( QPopupMenu *m )
00851 {
00852     QWindowsStyle::polishPopupMenu( m );
00853     m->setLineWidth( 1 );
00854 }
00855 
00858 int FlatStyle::extraPopupMenuItemWidth( bool checkable, int maxpmw, QMenuItem* mi, const QFontMetrics& /*fm*/ )
00859 {
00860 #ifndef QT_NO_MENUDATA
00861     int w = 2*motifItemHMargin + 2*motifItemFrame; // a little bit of border can never harm
00862 
00863     if ( mi->isSeparator() )
00864         return 10; // arbitrary
00865     else if ( mi->pixmap() )
00866         w += mi->pixmap()->width();     // pixmap only
00867 
00868     if ( !mi->text().isNull() ) {
00869         if ( mi->text().find('\t') >= 0 )       // string contains tab
00870             w += motifTabSpacing;
00871     }
00872 
00873     if ( maxpmw ) { // we have iconsets
00874         w += maxpmw;
00875         w += 6; // add a little extra border around the iconset
00876     }
00877 
00878     if ( checkable && maxpmw < windowsCheckMarkWidth ) {
00879         w += windowsCheckMarkWidth - maxpmw; // space for the checkmarks
00880     }
00881 
00882     if ( maxpmw > 0 || checkable ) // we have a check-column ( iconsets or checkmarks)
00883         w += motifCheckMarkHMargin; // add space to separate the columns
00884 
00885     w += windowsRightBorder; // windows has a strange wide border on the right side
00886 
00887     return w;
00888 #endif
00889 }
00890 
00893 int FlatStyle::popupMenuItemHeight( bool /*checkable*/, QMenuItem* mi, const QFontMetrics& fm )
00894 {
00895 #ifndef QT_NO_MENUDATA
00896     int h = 0;
00897     if ( mi->isSeparator() )                    // separator height
00898         h = motifSepHeight;
00899     else if ( mi->pixmap() )            // pixmap height
00900         h = mi->pixmap()->height() + 2*motifItemFrame;
00901     else                                        // text height
00902         h = fm.height() + 2*motifItemVMargin + 2*motifItemFrame - 1;
00903 
00904     if ( !mi->isSeparator() && mi->iconSet() != 0 ) {
00905         h = QMAX( h, mi->iconSet()->pixmap().height() + 2*motifItemFrame );
00906     }
00907     if ( mi->custom() )
00908         h = QMAX( h, mi->custom()->sizeHint().height() + 2*motifItemVMargin + 2*motifItemFrame ) - 1;
00909     return h;
00910 #endif
00911 }
00912 
00913 void FlatStyle::drawPopupMenuItem( QPainter* p, bool checkable, int maxpmw, int tab, QMenuItem* mi,
00914                                        const QPalette& pal,
00915                                        bool act, bool enabled, int x, int y, int w, int h)
00916 {
00917 #ifndef QT_NO_MENUDATA
00918     const QColorGroup & g = pal.active();
00919     bool dis      = !enabled;
00920     QColorGroup itemg = dis ? pal.disabled() : pal.active();
00921 
00922     if ( checkable )
00923         maxpmw = QMAX( maxpmw, 8 ); // space for the checkmarks
00924 
00925     int checkcol          =     maxpmw;
00926 
00927     if ( mi && mi->isSeparator() ) {                    // draw separator
00928         p->setPen( g.dark() );
00929         p->drawLine( x, y, x+w, y );
00930         return;
00931     }
00932 
00933     QBrush fill = act? g.brush( QColorGroup::Highlight ) :
00934                             g.brush( QColorGroup::Button );
00935     p->fillRect( x, y, w, h, fill);
00936 
00937     if ( !mi )
00938         return;
00939 
00940     if ( mi->isChecked() ) {
00941         if ( act && !dis ) {
00942             qDrawShadePanel( p, x, y, checkcol, h,
00943                              g, TRUE, 1, &g.brush( QColorGroup::Button ) );
00944         } else {
00945             qDrawShadePanel( p, x, y, checkcol, h,
00946                              g, TRUE, 1, &g.brush( QColorGroup::Midlight ) );
00947         }
00948     } else if ( !act ) {
00949         p->fillRect(x, y, checkcol , h,
00950                     g.brush( QColorGroup::Button ));
00951     }
00952 
00953     if ( mi->iconSet() ) {              // draw iconset
00954         QIconSet::Mode mode = dis ? QIconSet::Disabled : QIconSet::Normal;
00955         if (act && !dis )
00956             mode = QIconSet::Active;
00957     QPixmap pixmap;
00958     if ( mode == QIconSet::Disabled )
00959         pixmap = mi->iconSet()->pixmap( QIconSet::Automatic, mode );
00960     else
00961         pixmap = mi->iconSet()->pixmap();
00962         int pixw = pixmap.width();
00963         int pixh = pixmap.height();
00964         if ( act && !dis ) {
00965             if ( !mi->isChecked() )
00966                 qDrawShadePanel( p, x, y, checkcol, h, g, FALSE,  1, &g.brush( QColorGroup::Button ) );
00967         }
00968         QRect cr( x, y, checkcol, h );
00969         QRect pmr( 0, 0, pixw, pixh );
00970         pmr.moveCenter( cr.center() );
00971         p->setPen( itemg.text() );
00972         p->drawPixmap( pmr.topLeft(), pixmap );
00973 
00974         QBrush fill = act? g.brush( QColorGroup::Highlight ) :
00975                               g.brush( QColorGroup::Button );
00976         p->fillRect( x+checkcol + 1, y, w - checkcol - 1, h, fill);
00977     } else  if ( checkable ) {  // just "checking"...
00978         int mw = checkcol + motifItemFrame;
00979         int mh = h - 2*motifItemFrame;
00980         if ( mi->isChecked() ) {
00981             drawCheckMark( p, x + motifItemFrame + 2,
00982                            y+motifItemFrame, mw, mh, itemg, act, dis );
00983         }
00984     }
00985 
00986     p->setPen( act ? g.highlightedText() : g.buttonText() );
00987 
00988     QColor discol;
00989     if ( dis ) {
00990         discol = itemg.text();
00991         p->setPen( discol );
00992     }
00993 
00994     int xm = motifItemFrame + checkcol + motifItemHMargin;
00995 
00996     if ( mi->custom() ) {
00997         int m = motifItemVMargin;
00998         p->save();
00999         if ( dis && !act ) {
01000             p->setPen( g.light() );
01001             mi->custom()->paint( p, itemg, act, enabled,
01002                                  x+xm+1, y+m+1, w-xm-tab+1, h-2*m );
01003             p->setPen( discol );
01004         }
01005         mi->custom()->paint( p, itemg, act, enabled,
01006                              x+xm, y+m, w-xm-tab+1, h-2*m );
01007         p->restore();
01008     }
01009     QString s = mi->text();
01010     if ( !s.isNull() ) {                        // draw text
01011         int t = s.find( '\t' );
01012         int m = motifItemVMargin;
01013         const int text_flags = AlignVCenter|ShowPrefix | DontClip | SingleLine;
01014         if ( t >= 0 ) {                         // draw tab text
01015             if ( dis && !act ) {
01016                 p->setPen( g.light() );
01017                 p->drawText( x+w-tab-windowsRightBorder-motifItemHMargin-motifItemFrame+1,
01018                              y+m+1, tab, h-2*m, text_flags, s.mid( t+1 ));
01019                 p->setPen( discol );
01020             }
01021             p->drawText( x+w-tab-windowsRightBorder-motifItemHMargin-motifItemFrame,
01022                          y+m, tab, h-2*m, text_flags, s.mid( t+1 ) );
01023         }
01024         if ( dis && !act )
01025             p->setPen( discol );
01026         p->drawText( x+xm, y+m, w-xm-tab+1, h-2*m, text_flags, s, t );
01027     } else if ( mi->pixmap() ) {                        // draw pixmap
01028         QPixmap *pixmap = mi->pixmap();
01029         if ( pixmap->depth() == 1 )
01030             p->setBackgroundMode( OpaqueMode );
01031         p->drawPixmap( x+xm, y+motifItemFrame, *pixmap );
01032         if ( pixmap->depth() == 1 )
01033             p->setBackgroundMode( TransparentMode );
01034     }
01035     if ( mi->popup() ) {                        // draw sub menu arrow
01036         int dim = (h-2*motifItemFrame) / 2;
01037         if ( act ) {
01038             if ( !dis )
01039                 discol = white;
01040             QColorGroup g2( discol, g.highlight(),
01041                             white, white,
01042                             dis ? discol : white,
01043                             discol, white );
01044             drawArrow( p, RightArrow, FALSE,
01045                                x+w - motifArrowHMargin - motifItemFrame - dim,  y+h/2-dim/2,
01046                                dim, dim, g2, TRUE );
01047         } else {
01048             drawArrow( p, RightArrow,
01049                                FALSE,
01050                                x+w - motifArrowHMargin - motifItemFrame - dim,  y+h/2-dim/2,
01051                                dim, dim, g, mi->isEnabled() );
01052         }
01053     }
01054 #endif
01055 }
01056 
01057 void FlatStyle::getButtonShift( int &x, int &y )
01058 {
01059     x = 0; y = 0;
01060 }
01061 
01062 //===========================================================================
01063 
01064 FlatStyleImpl::FlatStyleImpl()
01065     : flat(0)
01066 {
01067 }
01068 
01069 FlatStyleImpl::~FlatStyleImpl()
01070 {
01071     // We do not delete the style because Qt does that when a new style
01072     // is set.
01073 }
01074 
01075 QStyle *FlatStyleImpl::style()
01076 {
01077     if ( !flat )
01078         flat = new FlatStyle();
01079     return flat;
01080 }
01081 
01082 QString FlatStyleImpl::name() const
01083 {
01084     return qApp->translate("FlatStyle", "Flat", "Name of the style Flat");
01085 }
01086 
01087 QRESULT FlatStyleImpl::queryInterface( const QUuid &uuid, QUnknownInterface **iface )
01088 {
01089     *iface = 0;
01090     if ( uuid == IID_QUnknown )
01091         *iface = this;
01092     else if ( uuid == IID_Style )
01093         *iface = this;
01094     else
01095         return QS_FALSE;
01096 
01097     (*iface)->addRef();
01098     return QS_OK;
01099 }
01100 
01101 Q_EXPORT_INTERFACE()
01102 {
01103     Q_CREATE_INSTANCE( FlatStyleImpl )
01104 }
01105 
01106 #include "flat.moc"

Generated on Sat Nov 5 16:17:17 2005 for OPIE by  doxygen 1.4.2