• Skip to content
  • Skip to link menu
KDE 4.1 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

KStyles

highcontrast.cpp

Go to the documentation of this file.
00001 /*
00002  * High Contrast Style (version 1.0)
00003  *     Copyright (C) 2004 Olaf Schmidt <ojschmidt@kde.org>
00004  *
00005  * Derived from Axes Style
00006  *     Copyright (C) 2003 Maksim Orlovich <orlovich@cs.rochester.edu>
00007  * 
00008  * Axes Style based on KDE 3 HighColor Style,
00009  *     Copyright (C) 2001-2002 Karol Szwed      <gallium@kde.org>
00010  *               (C) 2001-2002 Fredrik Höglund  <fredrik@kde.org>
00011  * 
00012  * This library is free software; you can redistribute it and/or
00013  * modify it under the terms of the GNU Library General Public
00014  * License version 2 as published by the Free Software Foundation.
00015  *
00016  * This library is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019  * Library General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU Library General Public License
00022  * along with this library; see the file COPYING.LIB.  If not, write to
00023  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00024  * Boston, MA 02110-1301, USA.
00025  */
00026 
00027 #include "highcontrast.h"
00028 #include "highcontrast.moc"
00029 
00030 #include <QtGui/qdrawutil.h>
00031 #include <QtGui/QPainter>
00032 #include <Qt3Support/Q3PointArray>
00033 #include <QtGui/QStylePlugin>
00034 
00035 #include <QtGui/QFont>
00036 #include <QtGui/QComboBox>
00037 #include <Qt3Support/Q3Header>
00038 #include <QtGui/QMenuBar>
00039 #include <QtGui/QPushButton>
00040 #include <QtGui/QScrollBar>
00041 #include <QtGui/QSlider>
00042 #include <QtGui/QTabBar>
00043 #include <QtGui/QToolButton>
00044 #include <Qt3Support/Q3ToolBar>
00045 #include <QtGui/QMenu>
00046 #include <QtGui/QProgressBar>
00047 #include <Qt3Support/Q3ListView>
00048 #include <QtCore/QSettings>
00049 
00050 #include <kdrawutil.h>
00051 
00052 // -- Style Plugin Interface -------------------------
00053 class HighContrastStylePlugin : public QStylePlugin
00054 {
00055     public:
00056         HighContrastStylePlugin() {}
00057         ~HighContrastStylePlugin() {}
00058 
00059         QStringList keys() const
00060         {
00061             return QStringList() << "HighContrast";
00062         }
00063 
00064         QStyle* create( const QString& key )
00065         {
00066             if ( key == "highcontrast" )
00067                 return new HighContrastStyle();
00068             return 0;
00069         }
00070 };
00071 
00072 Q_EXPORT_PLUGIN (HighContrastStylePlugin)
00073 // ---------------------------------------------------
00074 
00075 
00076 
00077 static const int itemFrame       = 1;
00078 static const int itemHMargin     = 3;
00079 static const int itemVMargin     = 0;
00080 static const int arrowHMargin    = 6;
00081 static const int rightBorder     = 12;
00082 
00083 
00084 void addOffset (QRect* r, int offset, int lineWidth = 0)
00085 {
00086     int offset1 = offset;
00087     int offset2 = offset;
00088 
00089     *r = r->normalized();
00090 
00091     if (lineWidth > 0)
00092     {
00093         offset1 += lineWidth/2;
00094         offset2 += lineWidth - lineWidth/2 - 1;
00095     }
00096 
00097     if (offset1 + offset2 > r->width())
00098         r->adjust (r->width()/2, 0, - (r->width() - r->width()/2), 0);
00099     else
00100         r->adjust (offset1, 0, -offset2, 0);
00101 
00102     if (offset1 + offset2 > r->height())
00103         r->adjust (0, r->height()/2, 0, - (r->height() - r->height()/2));
00104     else
00105         r->adjust (0, offset1, 0, -offset2);
00106 }
00107 
00108 
00109 // ---------------------------------------------------------------------------
00110 
00111 HighContrastStyle::HighContrastStyle()
00112     : KStyle( 0, ThreeButtonScrollBar )
00113 {
00114     QSettings settings;
00115     settings.beginGroup("/highcontraststyle/Settings/");
00116     bool useWideLines = settings.readBoolEntry("wideLines", false);
00117     hoverWidget = 0L;
00118     basicLineWidth = useWideLines ? 4 : 2;
00119 }
00120 
00121 
00122 HighContrastStyle::~HighContrastStyle()
00123 {
00124 }
00125 
00126 
00127 void HighContrastStyle::polish( QPalette& pal )
00128 {
00129     //We do not want the disabled widgets to be grayed out, 
00130     //as that may be hard indeed (and since we use crossed-out text instead),
00131     //so we make disabled colors be the same as active foreground and
00132     //background colour
00133     for (int c = 0; c < QPalette::NColorRoles; ++c)
00134         switch (c)
00135         {
00136             case QPalette::Button:
00137             case QPalette::Base:
00138             case QPalette::Highlight:
00139                 pal.setColor(QPalette::Disabled, QPalette::ColorRole(c), pal.color(QPalette::Active, QPalette::Background));
00140                 break;
00141             case QPalette::ButtonText:
00142             case QPalette::Text:
00143             case QPalette::HighlightedText:
00144                 pal.setColor(QPalette::Disabled, QPalette::ColorRole(c), pal.color(QPalette::Active, QPalette::Foreground));
00145                 break;
00146             default:
00147                 pal.setColor(QPalette::Disabled, QPalette::ColorRole(c), pal.color(QPalette::Active, QPalette::ColorRole(c)));
00148         }
00149 }
00150 
00151 
00152 void HighContrastStyle::polish (QWidget* widget)
00153 {
00154     if (widget->inherits ("QButton")
00155            || widget->inherits ("QComboBox")
00156            || widget->inherits ("QSpinWidget")
00157            || widget->inherits ("QLineEdit")
00158            || widget->inherits ("QTextEdit"))
00159     {
00160         widget->installEventFilter (this);
00161 
00162         Q3SpinWidget* spinwidget = dynamic_cast<Q3SpinWidget*>(widget);
00163         if (spinwidget && spinwidget->editWidget())
00164             spinwidget->editWidget()->installEventFilter (this);
00165     }
00166 
00167     KStyle::polish (widget);
00168 }
00169 
00170 
00171 void HighContrastStyle::unPolish (QWidget* widget)
00172 {
00173     if (widget->inherits ("QWidget") || widget->inherits ("QComboBox") || widget->inherits ("QSpinWidget") || widget->inherits ("QLineEdit") || widget->inherits ("QTextEdit"))
00174         widget->removeEventFilter (this);
00175     KStyle::unPolish (widget);
00176 }
00177 
00178 void HighContrastStyle::setColorsNormal (QPainter* p, const QColorGroup& cg, int flags, int highlight) const
00179 {
00180     setColorsByState (p, cg, cg.foreground(), cg.background(), flags, highlight);
00181 }
00182 
00183 void HighContrastStyle::setColorsButton (QPainter* p, const QColorGroup& cg, int flags, int highlight) const
00184 {
00185     setColorsByState (p, cg, cg.buttonText(), cg.button(), flags, highlight);
00186 }
00187 
00188 void HighContrastStyle::setColorsText (QPainter* p, const QColorGroup& cg, int flags, int highlight) const
00189 {
00190     setColorsByState (p, cg, cg.text(), cg.base(), flags, highlight);
00191 }
00192 
00193 void HighContrastStyle::setColorsHighlight (QPainter* p, const QColorGroup& cg, int flags) const
00194 {
00195     setColorsByState (p, cg, cg.highlightedText(), cg.highlight(), flags, 0);
00196 }
00197 
00198 void HighContrastStyle::setColorsByState (QPainter* p, const QColorGroup& cg, const QColor& fg, const QColor& bg, int flags, int highlight) const
00199 {
00200     QFont font = p->font();
00201     font.setStrikeOut (! (flags & Style_Enabled));
00202     p->setFont (font);
00203 
00204     if ((flags & Style_Enabled) && (flags & highlight))
00205     {
00206         p->setPen  (QPen (cg.highlightedText(), basicLineWidth, flags & Style_Enabled ? Qt::SolidLine : Qt::DotLine));
00207         p->setBackgroundColor (cg.highlight());
00208     }
00209     else
00210     {
00211         p->setPen  (QPen (fg, basicLineWidth, flags & Style_Enabled ? Qt::SolidLine : Qt::DotLine));
00212         p->setBackgroundColor (bg);
00213     }
00214 
00215     p->setBrush (QBrush ());
00216 }
00217 
00218 void HighContrastStyle::drawRect (QPainter* p, QRect r, int offset, bool filled) const
00219 {
00220     addOffset (&r, offset, p->pen().width());
00221     if (filled)
00222         p->fillRect (r, p->background().color());
00223 
00224     p->drawRect (r);
00225 }
00226 
00227 void HighContrastStyle::drawRoundRect (QPainter* p, QRect r, int offset, bool filled) const
00228 {
00229     int lineWidth = p->pen().width();
00230     if ((r.width() >= 5*lineWidth + 2*offset) && (r.height() >= 5*lineWidth + 2*offset))
00231     {
00232         QRect r2 (r);
00233         addOffset (&r2, offset, lineWidth);
00234 
00235         addOffset (&r, offset); 
00236         QRect r3 (r);
00237         addOffset (&r3, lineWidth);
00238 
00239         p->save();
00240         p->setPen (Qt::NoPen);
00241         if (filled)
00242             p->fillRect (r3, p->background().color());
00243         p->drawRect (r3);
00244         p->restore();
00245         
00246         p->drawLine (r.left()+lineWidth, r2.top(), r.right()+1-lineWidth, r2.top());
00247         p->fillRect (r.left()+1, r.top()+1, lineWidth, lineWidth, p->pen().color());
00248         p->drawLine (r2.left(), r.top()+lineWidth, r2.left(), r.bottom()+1-lineWidth);
00249         p->fillRect (r.left()+1, r.bottom()-lineWidth, lineWidth, lineWidth, p->pen().color());
00250         p->drawLine (r.left()+lineWidth, r2.bottom(), r.right()+1-lineWidth, r2.bottom());
00251         p->fillRect (r.right()-lineWidth, r.bottom()-lineWidth, lineWidth, lineWidth, p->pen().color());
00252         p->drawLine (r2.right(), r.top()+lineWidth, r2.right(), r.bottom()+1-lineWidth);
00253         p->fillRect (r.right()-lineWidth, r.top()+1, lineWidth, lineWidth, p->pen().color());
00254     }
00255     else
00256         drawRect (p, r, offset, filled);
00257 }
00258 
00259 void HighContrastStyle::drawEllipse (QPainter* p, QRect r, int offset, bool filled) const
00260 {
00261     addOffset (&r, offset, p->pen().width());
00262 
00263     if (filled) {
00264         p->save();
00265         p->setBrush (p->background().color());
00266         p->drawRoundRect (r, 99.0, 99.0);
00267         p->restore();
00268     }
00269     
00270     p->drawRoundRect (r, 99.0, 99.0);
00271 }
00272 
00273 void HighContrastStyle::drawArrow (QPainter* p, QRect r, PrimitiveElement arrow, int offset) const
00274 {
00275     p->save();
00276     addOffset (&r, offset);
00277 
00278     QPoint center = r.center();
00279     if (r.height() < r.width())
00280         r.setWidth (r.height());
00281     if (r.width() % 2 != 0)
00282         r.setWidth (r.width() - 1);
00283     r.setHeight (r.width());
00284     r.moveCenter (center);
00285             
00286     Q3PointArray points (3);
00287     switch (arrow) {
00288         case PE_ArrowUp:
00289         case PE_SpinWidgetUp:
00290         case PE_SpinWidgetPlus: {
00291             points.setPoint (0, r.bottomLeft());
00292             points.setPoint (1, r.bottomRight());
00293             points.setPoint (2, r.center().x(), r.top() + r.height()/7);
00294             break;
00295         }
00296         case PE_ArrowDown:
00297         case PE_SpinWidgetDown:
00298         case PE_SpinWidgetMinus: {
00299             points.setPoint (0, r.topLeft());
00300             points.setPoint (1, r.topRight());
00301             points.setPoint (2, r.center().x(), r.bottom() - r.height()/7);
00302             break;
00303         }
00304         case PE_ArrowLeft: {
00305             points.setPoint (0, r.topRight());
00306             points.setPoint (1, r.bottomRight());
00307             points.setPoint (2, r.left() + r.width()/7, r.center().y());
00308             break;
00309         }
00310         default: {
00311             points.setPoint (0, r.topLeft());
00312             points.setPoint (1, r.bottomLeft());
00313             points.setPoint (2, r.right() - r.width()/7, r.center().y());
00314         }
00315     }
00316 
00317     p->setPen (p->pen().color());
00318     p->setBrush (p->pen().color());
00319     p->drawPolygon (points);
00320     p->restore();
00321 }
00322 
00323 // This function draws primitive elements
00324 void HighContrastStyle::drawPrimitive (PrimitiveElement pe,
00325                                 QPainter *p,
00326                                 const QRect &r,
00327                                 const QColorGroup &cg,
00328                                 SFlags flags,
00329                                 const QStyleOption& opt ) const
00330 {
00331     switch(pe)
00332     {
00333         case PE_StatusBarSection: {
00334             //### TODO: Not everything uses this!
00335             setColorsNormal (p, cg, Style_Enabled);
00336             drawRect (p, r);
00337             break;
00338         }
00339         // BUTTONS
00340         // -------------------------------------------------------------------
00341         case PE_ButtonDefault:
00342         case PE_ButtonDropDown:
00343         case PE_ButtonCommand:
00344         case PE_ButtonTool:
00345         case PE_ButtonBevel: {
00346             setColorsButton (p, cg, flags, Style_On|Style_MouseOver|Style_Down);
00347             drawRoundRect (p, r, 0, false);
00348             break;
00349         }
00350 
00351         // FOCUS RECT
00352         // -------------------------------------------------------------------
00353         case PE_FocusRect: {
00354             p->save();
00355             p->setBrush (QBrush ());
00356             p->setPen (QPen (cg.highlight(), basicLineWidth, Qt::SolidLine));
00357             drawRoundRect (p, r, basicLineWidth, false);
00358             p->setPen (QPen (cg.highlightedText(), basicLineWidth, Qt::DashLine));
00359             drawRoundRect (p, r, basicLineWidth, false);
00360             p->restore();
00361             break;
00362         }
00363 
00364         case PE_HeaderArrow: {
00365             setColorsButton (p, cg, flags, 0);
00366             drawArrow (p, r, flags & Style_Down ? PE_ArrowDown : PE_ArrowUp, 2*basicLineWidth);
00367             break;
00368         }
00369         // HEADER SECTION
00370         // -------------------------------------------------------------------
00371         case PE_HeaderSection: {
00372             setColorsButton (p, cg, flags, 0);
00373             drawRect (p, r);
00374             break;
00375         }
00376 
00377 
00378         // SCROLLBAR
00379         // -------------------------------------------------------------------
00380         case PE_ScrollBarSlider: {
00381             setColorsNormal (p, cg);
00382             p->fillRect (r, p->background().color());
00383 
00384             if (flags & Style_Enabled) {
00385                 setColorsHighlight (p, cg, flags);
00386                 drawRoundRect (p, r);
00387 
00388                 if (r.width() >= 7*basicLineWidth && r.height() >= 7*basicLineWidth) {
00389                     QRect r2 (r);
00390                     r2.setWidth (4*basicLineWidth);
00391                     r2.setHeight (4*basicLineWidth);
00392                     r2.moveCenter (r.center());
00393                     drawRect (p, r2, 0, false);
00394                 }
00395             }
00396             break;
00397         }
00398 
00399         case PE_ScrollBarAddPage:
00400         case PE_ScrollBarSubPage: {
00401             setColorsNormal (p, cg);
00402             p->fillRect (r, p->background().color());
00403 
00404             QRect r2 (r);
00405             if (flags & Style_Horizontal)
00406             {
00407                 if (r2.height() > 5*basicLineWidth)
00408                 {
00409                     r2.setHeight (5*basicLineWidth);
00410                     r2.moveCenter (r.center());
00411                 }
00412             }
00413             else
00414             {
00415                 if (r2.width() > 5*basicLineWidth)
00416                 {
00417                     r2.setWidth (5*basicLineWidth);
00418                     r2.moveCenter (r.center());
00419                 }
00420             }
00421             setColorsText (p, cg, flags);
00422             drawRect (p, r2);
00423             
00424             if (flags & Style_Horizontal)
00425                 r2.adjust (0, basicLineWidth, 0, -basicLineWidth);
00426             else
00427                 r2.adjust (basicLineWidth, 0, -basicLineWidth, 0);
00428             QPen pen = p->pen();
00429             pen.setColor (p->background().color());
00430             p->setPen (pen);
00431             drawRect (p, r2);
00432 
00433             break;
00434         }
00435 
00436         case PE_ScrollBarAddLine:
00437         case PE_ScrollBarSubLine:
00438         case PE_ScrollBarFirst:
00439         case PE_ScrollBarLast: {
00440             setColorsNormal (p, cg);
00441             p->fillRect (r, p->background().color());
00442 
00443             if (flags & Style_Enabled) {
00444                 setColorsButton (p, cg, flags);
00445                 drawRoundRect (p, r);
00446                 if (pe == PE_ScrollBarAddLine)
00447                     drawArrow (p, r, flags & Style_Horizontal ? PE_ArrowRight : PE_ArrowDown, r.height()/3);
00448                 else if (pe == PE_ScrollBarSubLine)
00449                     drawArrow (p, r, flags & Style_Horizontal ? PE_ArrowLeft : PE_ArrowUp, r.height()/3);
00450             }
00451             break;
00452         }
00453 
00454         
00455         case PE_ProgressBarChunk: {
00456             p->fillRect (r, Qt::color1);
00457             break;
00458         }
00459 
00460 
00461         // CHECKBOX
00462         // -------------------------------------------------------------------
00463         case PE_Indicator: {
00464             setColorsText (p, cg, flags);
00465 
00466             //Draw the outer rect
00467             drawRect (p, r);
00468 
00469             if (!(flags & Style_Off))
00470             {
00471                 QRect r2 (r);
00472                 addOffset (&r2, basicLineWidth);
00473                 if (flags & Style_On)
00474                 {
00475                     p->drawLine (r2.topLeft(), r2.bottomRight());
00476                     p->drawLine (r2.bottomLeft(), r2.topRight());
00477                 }
00478                 else
00479                 {   // Tristate
00480                     p->drawLine (r2.left(), r2.top()+r2.width()/2, r2.right(), r2.top()+r2.width()/2);
00481                 }
00482                 QPen pen = p->pen();
00483                 pen.setColor (p->background().color());
00484                 p->setPen (pen);
00485                 drawRect (p, r2, 0, false);
00486             }
00487             break;
00488         }
00489         case PE_IndicatorMask: {
00490             p->fillRect (r, Qt::color1);
00491             break;
00492         }
00493         case PE_CheckMark: {
00494             setColorsText (p, cg, flags);
00495 
00496             if (flags & Style_On)
00497             {
00498                 p->drawLine (r.topLeft(), r.bottomRight());
00499                 p->drawLine (r.bottomLeft(), r.topRight());
00500             }
00501             break;
00502         }
00503 
00504         // RADIOBUTTON (exclusive indicator)
00505         // -------------------------------------------------------------------
00506         case PE_ExclusiveIndicator: {
00507             setColorsText (p, cg, flags);
00508             drawEllipse (p, r);
00509 
00510             // Indicator "dot"
00511             if (flags & Style_On) {
00512                 p->setBackgroundColor (p->pen().color());
00513                 drawEllipse (p, r, 2*p->pen().width());
00514             }
00515 
00516             break;
00517         }
00518         case PE_ExclusiveIndicatorMask: {
00519             p->fillRect (r, Qt::color0);
00520             p->setBackgroundColor (Qt::color1);
00521             p->setPen (Qt::NoPen);
00522             p->setBrush (Qt::color1);
00523             p->drawEllipse (r);
00524             break;
00525         }
00526 
00527 
00528         // SPLITTER/DOCKWINDOW HANDLES
00529         // -------------------------------------------------------------------
00530         case PE_DockWindowResizeHandle:
00531         case PE_Splitter: {
00532             setColorsButton (p, cg, flags);
00533             p->fillRect (r, p->background().color());
00534             
00535             p->setPen (QPen (p->pen().color(), 1, Qt::DashLine));
00536             if (flags & Style_Horizontal)
00537                 p->drawLine (r.center().x(), r.top(), r.center().x(), r.bottom());
00538             else
00539                 p->drawLine (r.left(), r.center().y(), r.right(), r.center().y());
00540             break;
00541         }
00542 
00543 
00544         // GENERAL PANELS
00545         // -------------------------------------------------------------------
00546         case PE_Panel:
00547         case PE_GroupBoxFrame:
00548         case PE_PanelPopup: {
00549             setColorsNormal (p, cg, flags, 0);
00550             if (!opt.isDefault())
00551             {
00552                 QPen pen = p->pen();
00553                 pen.setWidth (opt.lineWidth());
00554                 p->setPen (pen);
00555             }
00556             if (pe == PE_PanelPopup)
00557                 drawRect (p, r, 0, false);
00558             else 
00559                 drawRoundRect (p, r, 0, false);
00560             break;
00561         }
00562         case PE_WindowFrame:
00563         case PE_TabBarBase: {
00564             setColorsNormal (p, cg, flags, 0);
00565             drawRect (p, r, 0, false);
00566             break;
00567         }
00568         case PE_PanelLineEdit: {
00569             setColorsText (p, cg, flags, 0);
00570             drawRoundRect (p, r);
00571             if (flags & (Style_HasFocus | Style_Active))
00572                 drawPrimitive (PE_FocusRect, p, r, cg, flags, QStyleOption (p->background().color()));
00573             break;
00574         }
00575         case PE_PanelTabWidget:
00576         case PE_PanelGroupBox: {
00577             setColorsNormal (p, cg, flags, 0);
00578             drawRoundRect (p, r);
00579             break;
00580         }
00581         case PE_PanelMenuBar: {         // Menu
00582             p->fillRect (r, cg.background());
00583             break;
00584         }
00585         case PE_PanelDockWindow: {      // Toolbar
00586             p->fillRect (r, cg.button());
00587             break;
00588         }
00589 
00590 
00591 
00592         // SEPARATORS
00593         // -------------------------------------------------------------------
00594         case PE_Separator: {
00595             setColorsNormal (p, cg);
00596             p->fillRect (r, p->background().color());
00597             p->setPen (p->pen().color());
00598             if (flags & Style_Horizontal)
00599                 p->drawLine (r.center().x(), r.top()+basicLineWidth, r.center().x(), r.bottom()-basicLineWidth + 1);
00600             else
00601                 p->drawLine (r.left()+basicLineWidth, r.center().y(), r.right()-basicLineWidth + 1, r.center().y());
00602             break;
00603         }
00604         case PE_DockWindowSeparator: {
00605             setColorsButton (p, cg);
00606             p->fillRect (r, p->background().color());
00607             p->setPen (p->pen().color());
00608             if (flags & Style_Horizontal)
00609                 p->drawLine (r.center().x(), r.top()+basicLineWidth, r.center().x(), r.bottom()-basicLineWidth);
00610             else
00611                 p->drawLine (r.left()+basicLineWidth, r.center().y(), r.right()-basicLineWidth, r.center().y());
00612             break;
00613         }
00614 
00615 
00616         // ARROWS
00617         // -------------------------------------------------------------------
00618         case PE_ArrowUp:
00619         case PE_ArrowDown:
00620         case PE_ArrowRight:
00621         case PE_ArrowLeft:
00622         case PE_SpinWidgetPlus:
00623         case PE_SpinWidgetUp:
00624         case PE_SpinWidgetMinus:
00625         case PE_SpinWidgetDown: {
00626             setColorsNormal (p, cg, flags);
00627             drawArrow (p, r, pe);
00628             break;
00629         }
00630 
00631         default: {
00632             KStyle::drawPrimitive( pe, p, r, cg, flags, opt );
00633         }
00634     }
00635 }
00636 
00637 
00638 void HighContrastStyle::drawKStylePrimitive (KStylePrimitive kpe,
00639                                         QPainter* p,
00640                                         const QWidget* widget,
00641                                         const QRect &r,
00642                                         const QColorGroup &cg,
00643                                         SFlags flags,
00644                                         const QStyleOption &opt ) const
00645 {
00646     if ( widget == hoverWidget )
00647         flags |= Style_MouseOver;
00648 
00649     switch ( kpe )
00650     {
00651         // TOOLBAR HANDLE
00652         // -------------------------------------------------------------------
00653         case KPE_ToolBarHandle:
00654         case KPE_DockWindowHandle:
00655         case KPE_GeneralHandle:
00656         {
00657             setColorsButton (p, cg);
00658             p->fillRect (r, p->background().color());
00659             p->setBrush (QBrush (p->pen().color(), Qt::BDiagPattern));
00660             drawRoundRect (p, r);
00661             break;
00662         }
00663 
00664 
00665         // SLIDER GROOVE
00666         // -------------------------------------------------------------------
00667         case KPE_SliderGroove: {
00668             setColorsText (p, cg, flags);
00669             QRect r2 (r);
00670             const QSlider *slider = dynamic_cast<const QSlider*>(widget);
00671             if (slider != 0)
00672             {
00673                 if (slider->orientation() == Qt::Horizontal)
00674                 {
00675                     if (r2.height() > 5*basicLineWidth)
00676                     {
00677                         r2.setHeight (5*basicLineWidth);
00678                         r2.moveCenter (r.center());
00679                     }
00680                 }
00681                 else
00682                 {
00683                     if (r2.width() > 5*basicLineWidth)
00684                     {
00685                         r2.setWidth (5*basicLineWidth);
00686                         r2.moveCenter (r.center());
00687                     }
00688                 }
00689             }
00690 
00691             drawRoundRect (p, r2);
00692             break;
00693         }
00694 
00695         // SLIDER HANDLE
00696         // -------------------------------------------------------------------
00697         case KPE_SliderHandle: {
00698             setColorsHighlight (p, cg, flags);
00699             drawRoundRect (p, r);
00700             break;
00701         }
00702 
00703         case KPE_ListViewExpander: {
00704             // TODO There is no pixelMetric associated with the
00705             // ListViewExpander in KStyle.
00706             // To have a properly large expander, the CC_ListView case of
00707             // drawComplexControl should be handled.
00708             // Probably it would be better to add a KPM_ListViewExpander metric
00709             // to the KStyle KStylePixelMetric enum, and have the KStyle
00710             // drawComplexControl handle it.
00711             PrimitiveElement direction;
00712             if (flags & Style_On) { // Collapsed = On
00713                 direction = PE_ArrowRight;
00714 
00715             } else {
00716                 direction = PE_ArrowDown;
00717             }
00718             setColorsText (p, cg, flags);
00719             drawArrow (p, r, direction);
00720             break;
00721         }
00722         case KPE_ListViewBranch: 
00723             // TODO Draw (thick) dotted line. Check kstyle.cpp
00724             // Fall down for now
00725         default:
00726             KStyle::drawKStylePrimitive( kpe, p, widget, r, cg, flags, opt);
00727     }
00728 }
00729 
00730 
00731 void HighContrastStyle::drawControl (ControlElement element,
00732                                 QPainter *p,
00733                                 const QWidget *widget,
00734                                 const QRect &r,
00735                                 const QColorGroup &cg,
00736                                 SFlags flags,
00737                                 const QStyleOption& opt ) const
00738 {
00739     if ( widget == hoverWidget )
00740         flags |= Style_MouseOver;
00741 
00742     switch (element)
00743     {
00744         // TABS
00745         // -------------------------------------------------------------------
00746         case CE_ToolBoxTab: {
00747             setColorsNormal (p, cg, flags, Style_Selected);
00748             drawRoundRect (p, r);
00749             break;
00750         }
00751 
00752         case CE_TabBarTab: {
00753             setColorsNormal (p, cg, flags, Style_Selected);
00754             drawRoundRect (p, r);
00755             
00756             const QTabBar *tb = static_cast< const QTabBar * >(widget);
00757             QTabBar::Shape shape = tb->shape();
00758             if (shape == QTabBar:: TriangularSouth || 
00759                 shape == QTabBar:: RoundedSouth) {
00760                 p->fillRect (r.left(), r.top(), 
00761                              r.width(), 2*basicLineWidth, 
00762                              p->pen().color());
00763                 p->fillRect (r.left()+basicLineWidth, 
00764                              flags & Style_Selected ? basicLineWidth : 2*basicLineWidth,
00765                              r.width()-2*basicLineWidth,
00766                              basicLineWidth,
00767                              p->background().color());
00768             } else {
00769                 p->fillRect (r.left(), r.bottom()-2*basicLineWidth+1, 
00770                              r.width(), 2*basicLineWidth, 
00771                              p->pen().color());
00772                 p->fillRect (r.left()+basicLineWidth, 
00773                              r.bottom()-2*basicLineWidth+1, 
00774                              r.width()-2*basicLineWidth,
00775                              flags & Style_Selected ? 2*basicLineWidth : basicLineWidth,
00776                              p->background().color());
00777             }
00778             break;
00779         }
00780 
00781 
00782         // PUSHBUTTON
00783         // -------------------------------------------------------------------
00784         case CE_PushButton: {
00785             QPushButton *button = (QPushButton*) widget;
00786             QRect br = r;
00787             bool btnDefault = button->isDefault();
00788 
00789             if (( btnDefault || button->autoDefault() ) && (button->isEnabled())) {
00790                 // Compensate for default indicator
00791                 static int di = pixelMetric( PM_ButtonDefaultIndicator );
00792                 addOffset (&br, di);
00793             }
00794 
00795             if ( btnDefault && (button->isEnabled()))
00796                 drawPrimitive( PE_ButtonDefault, p, r, cg, flags );
00797 
00798             drawPrimitive( PE_ButtonCommand, p, br, cg, flags );
00799 
00800             break;
00801         }
00802 
00803 
00804         // LABEL
00805         // -------------------------------------------------------------------
00806         case CE_ProgressBarLabel:
00807         case CE_TabBarLabel:
00808         case CE_RadioButtonLabel:
00809         case CE_CheckBoxLabel:
00810         case CE_ToolButtonLabel:
00811         case CE_PushButtonLabel: {
00812             const QPixmap* pixmap = 0;
00813             QPixmap icon;
00814             QString text;
00815             bool popup = false;
00816             
00817             QIcon::Mode  mode  = flags & Style_Enabled ? ((flags & Style_HasFocus) ? QIcon::Active : QIcon::Normal) : QIcon::Disabled;
00818             QIcon::State state = flags & Style_On ? QIcon::On : QIcon::Off;
00819 
00820             int x, y, w, h;
00821             r.rect( &x, &y, &w, &h );
00822             
00823             if (element == CE_ProgressBarLabel) {
00824                 QProgressBar* progressbar = (QProgressBar*) widget;
00825                 text = progressbar->progressString();
00826                 setColorsNormal (p, cg, flags);
00827             }
00828             else if (element == CE_TabBarLabel) {
00829                 if (!opt.isDefault()) {
00830                     QTab* tab = opt.tab();
00831                     text = tab->text();
00832                 }
00833                 setColorsNormal (p, cg, flags, Style_Selected);
00834             }
00835             else if (element == CE_ToolButtonLabel) {
00836                 QToolButton* toolbutton = (QToolButton*) widget;
00837                 text = toolbutton->text();
00838                 pixmap = toolbutton->pixmap();
00839                 if (!toolbutton->iconSet().isNull())
00840                     icon = toolbutton->iconSet().pixmap (QIcon::Small, mode, state);
00841                 popup = toolbutton->popup();
00842                 setColorsButton (p, cg, flags);
00843             }
00844             else if (element == CE_PushButtonLabel) {
00845                 QPushButton* pushbutton = (QPushButton*) widget;
00846                 text = pushbutton->text();
00847                 pixmap = pushbutton->pixmap();
00848                 if (pushbutton->iconSet() && !pushbutton->iconSet()->isNull())
00849                     icon = pushbutton->iconSet()->pixmap (QIcon::Small, mode, state);
00850                 popup = pushbutton->popup();
00851                 setColorsButton (p, cg, flags);
00852             }
00853             else {
00854                 const Q3Button* button = (const Q3Button*)widget;
00855                 pixmap = button->pixmap();
00856                 text = button->text();
00857                 setColorsNormal (p, cg);
00858             }
00859 
00860             // Does the button have a popup menu?
00861             if (popup) {
00862                 int dx = pixelMetric (PM_MenuButtonIndicator, widget);
00863                 drawArrow (p, QRect(x + w - dx - 2, y + 2, dx, h - 4), PE_ArrowDown);
00864                 w -= dx;
00865             }
00866 
00867             // Draw the icon if there is one
00868             if (!icon.isNull())
00869             {
00870                 // Center the iconset if there's no text or pixmap
00871                 if (text.isEmpty() && ((pixmap == 0) || pixmap->isNull()))
00872                     p->drawPixmap (x + (w - icon.width())  / 2,
00873                                    y + (h - icon.height()) / 2, icon);
00874                 else
00875                     p->drawPixmap (x + 4, y + (h - icon.height()) / 2, icon);
00876 
00877                 int  pw = icon.width();
00878                 x += pw + 4;
00879                 w -= pw + 4;
00880             }
00881 
00882             // Draw a focus rect if the button has focus
00883             if (flags & Style_HasFocus)
00884                 drawPrimitive (PE_FocusRect, p, r, cg, flags, QStyleOption (p->background().color()));
00885 
00886             // Draw the label itself
00887             QColor color = p->pen().color();
00888             drawItem (p, QRect(x, y, w, h),
00889                       (element == CE_RadioButtonLabel || element == CE_CheckBoxLabel || element == CE_ProgressBarLabel) ? Qt::AlignVCenter|Qt::AlignLeft|Qt::TextShowMnemonic : Qt::AlignCenter|Qt::TextShowMnemonic,
00890                       cg, flags & Style_Enabled, pixmap, text, -1, &color);
00891             break;
00892         }
00893 
00894         // MENUBAR BACKGROUND
00895         // -------------------------------------------------------------------
00896         case CE_MenuBarEmptyArea:
00897         {
00898             p->fillRect (r, cg.background());
00899             break;
00900         }
00901 
00902         // DOCKWINDOW BACKGROUND
00903         // -------------------------------------------------------------------
00904         case CE_DockWindowEmptyArea:
00905         {
00906             p->fillRect (r, cg.button());
00907             break;
00908         }
00909 
00910         // MENUBAR ITEM
00911         // -------------------------------------------------------------------
00912         case CE_MenuBarItem: {
00913             setColorsNormal (p, cg, flags, Style_Active|Style_MouseOver);
00914             p->fillRect (r, p->background().color());
00915             if (!opt.isDefault()) {
00916                 QMenuItem *mi = opt.menuItem();
00917 
00918                 QColor color = p->pen().color();
00919                 drawItem (p, r, Qt::AlignCenter | Qt::AlignVCenter | Qt::TextShowMnemonic
00920                         | Qt::TextDontClip | Qt::TextSingleLine, cg, flags,
00921                         mi->pixmap(), mi->text(), -1, &color);
00922             }
00923             break;
00924         }
00925 
00926         // CHECKBOX
00927         // -------------------------------------------------------------------
00928         case CE_CheckBox: {
00929             drawPrimitive (PE_Indicator, p, r, cg, flags);
00930             break;
00931         }
00932 
00933         // RADIOBUTTON
00934         // -------------------------------------------------------------------
00935         case CE_RadioButton: {
00936             drawPrimitive (PE_ExclusiveIndicator, p, r, cg, flags);
00937             break;
00938         }
00939 
00940         // PROGRESSBAR
00941         // -------------------------------------------------------------------
00942         case CE_ProgressBarGroove: {
00943             setColorsText (p, cg, flags);
00944             const QProgressBar *progressbar = dynamic_cast<const QProgressBar*>(widget);
00945             if (progressbar) {
00946                 QRect r2 (r);
00947                 r2.setLeft (p->boundingRect (r, Qt::AlignVCenter|Qt::AlignLeft|Qt::TextShowMnemonic, progressbar->progressString()).right()
00948                         + 4*basicLineWidth);
00949                 drawRoundRect (p, r2);
00950             }
00951             break;
00952         }
00953         case CE_ProgressBarContents: {
00954             const QProgressBar *progressbar = dynamic_cast<const QProgressBar*>(widget);
00955             if (progressbar)
00956             {
00957                 QRect r2 (r);
00958                 r2.setLeft (p->boundingRect (r, Qt::AlignVCenter|Qt::AlignLeft|Qt::TextShowMnemonic, progressbar->progressString()).right()
00959                         + 4*basicLineWidth);
00960                 long progress = r2.width() * progressbar->progress();
00961                 if (progressbar->totalSteps() > 0)
00962                 {
00963                     r2.setWidth (progress / progressbar->totalSteps());
00964                 }
00965                 else
00966                 {
00967                     int width = r2.width() / 5;
00968                     int left = progressbar->progress() % (2*(r2.width() - width));
00969                     if (left > r2.width() - width)
00970                         left = 2*(r2.width() - width) - left;
00971                     r2.setLeft (r2.left() + left);
00972                     r2.setWidth (width);
00973                 }
00974                 setColorsHighlight (p, cg, flags);
00975                 if (r2.width() > 0)
00976                     drawRoundRect (p, r2);
00977             }
00978             break;
00979         }
00980 
00981         // POPUPMENU ITEM
00982         // -------------------------------------------------------------------
00983         case CE_PopupMenuItem: {
00984             setColorsNormal (p, cg, flags, Style_Active|Style_MouseOver);
00985             p->fillRect (r, p->background().color());
00986 
00987             const QMenu *popupmenu = (const QMenu *) widget;
00988             QMenuItem *mi = opt.menuItem();
00989             if (!mi)
00990                 break;
00991 
00992             int  tab        = opt.tabWidth();
00993             int  checkcol   = opt.maxIconWidth();
00994             bool checkable  = popupmenu->isCheckable();
00995             bool reverse    = QApplication::isRightToLeft();
00996             int x, y, w, h;
00997             r.rect( &x, &y, &w, &h );
00998 
00999             if ( checkable )
01000                 checkcol = qMax( checkcol, 20 );
01001 
01002             // Are we a menu item separator?
01003             if ( mi->isSeparator() ) {
01004                 p->drawLine (r.left() + 1, r.center().y(), r.right(), r.center().y());
01005                 break;
01006             }
01007 
01008             // Do we have an icon?
01009             if ( mi->iconSet() && !mi->iconSet()->isNull() ) {
01010                 QIcon::Mode mode;
01011                 QRect cr = visualRect( QRect(x, y, checkcol, h), r );
01012 
01013                 // Select the correct icon from the iconset
01014                 if (!(flags & Style_Enabled))
01015                     mode = QIcon::Disabled;
01016                 else if (flags & Style_Active)
01017                     mode = QIcon::Active;
01018                 else
01019                     mode = QIcon::Normal;
01020 
01021                 // Draw the icon
01022                 QPixmap pixmap = mi->iconSet()->pixmap( QIcon::Small, mode );
01023                 QRect pmr( 0, 0, pixmap.width(), pixmap.height() );
01024                 pmr.moveCenter( cr.center() );
01025                 p->drawPixmap( pmr.topLeft(), pixmap );
01026 
01027                 // Do we have an icon and are checked at the same time?
01028                 // Then draw a square border around the icon
01029                 if ( checkable && mi->isChecked() )
01030                 {
01031                     drawRect (p, cr, 0, false);
01032                 }
01033             }
01034 
01035             // Are we checked? (This time without an icon)
01036             else if ( checkable && mi->isChecked() ) {
01037                 int cx = reverse ? x+w - checkcol : x;
01038 
01039                 QRect rc (cx, y, checkcol, h);
01040                 addOffset (&rc, 2*basicLineWidth);
01041                 QPoint center = rc.center();
01042                 if (rc.width() > rc.height())
01043                     rc.setWidth (rc.height());
01044                 else
01045                     rc.setHeight (rc.width());
01046                 rc.moveCenter (center);
01047                     
01048                 p->drawLine (rc.topLeft(), rc.bottomRight());
01049                 p->drawLine (rc.topRight(), rc.bottomLeft());
01050             }
01051 
01052             // Time to draw the menu item label...
01053             int xm = itemFrame + checkcol + itemHMargin; // X position margin
01054 
01055             int xp = reverse ? // X position
01056                     x + tab + rightBorder + itemHMargin + itemFrame - 1 :
01057                     x + xm;
01058 
01059             // Label width (minus the width of the accelerator portion)
01060             int tw = w - xm - tab - arrowHMargin - itemHMargin * 3 - itemFrame + 1;
01061 
01062             // Does the menu item draw it's own label?
01063             if ( mi->custom() ) {
01064                 int m = itemVMargin;
01065                 // Save the painter state in case the custom
01066                 // paint method changes it in some way
01067                 p->save();
01068                 mi->custom()->paint( p, cg, flags & Style_Active, flags & Style_Enabled, xp, y+m, tw, h-2*m );
01069                 p->restore();
01070             }
01071             else {
01072                 // The menu item doesn't draw it's own label
01073                 QString s = mi->text();
01074 
01075                 // Does the menu item have a text label?
01076                 if ( !s.isNull() ) {
01077                     int t = s.find( '\t' );
01078                     int m = itemVMargin;
01079                     int text_flags = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
01080                     text_flags |= reverse ? Qt::AlignRight : Qt::AlignLeft;
01081 
01082                     // Does the menu item have a tabstop? (for the accelerator text)
01083                     if ( t >= 0 ) {
01084                         int tabx = reverse ? x + rightBorder + itemHMargin + itemFrame :
01085                             x + w - tab - rightBorder - itemHMargin - itemFrame;
01086 
01087                         // Draw the right part of the label (accelerator text)
01088                         p->drawText( tabx, y+m, tab, h-2*m, text_flags, s.mid( t+1 ) );
01089                         s = s.left( t );
01090                     }
01091 
01092                     // Draw the left part of the label (or the whole label
01093                     // if there's no accelerator)
01094 
01095                     p->drawText( xp, y+m, tw, h-2*m, text_flags, s, t );
01096 
01097                 }
01098 
01099                 // The menu item doesn't have a text label
01100                 // Check if it has a pixmap instead
01101                 else if ( mi->pixmap() ) {
01102                     QPixmap *pixmap = mi->pixmap();
01103 
01104                     // Draw the pixmap
01105                     if ( pixmap->depth() == 1 )
01106                         p->setBackgroundMode( Qt::OpaqueMode );
01107 
01108                     int diffw = ( ( w - pixmap->width() ) / 2 )
01109                                     + ( ( w - pixmap->width() ) % 2 );
01110                     p->drawPixmap( x+diffw, y+itemFrame, *pixmap );
01111 
01112                     if ( pixmap->depth() == 1 )
01113                         p->setBackgroundMode( Qt::TransparentMode );
01114                 }
01115             }
01116 
01117             // Does the menu item have a submenu?
01118             if ( mi->popup() ) {
01119                 PrimitiveElement arrow = reverse ? PE_ArrowLeft : PE_ArrowRight;
01120                 int dim = pixelMetric(PM_MenuButtonIndicator);
01121                 QRect vr = visualRect( QRect( x + w - arrowHMargin - 2*itemFrame - dim,
01122                             y + h / 2 - dim / 2, dim, dim), r );
01123 
01124                 // Draw an arrow at the far end of the menu item
01125                 drawArrow (p, vr, arrow);
01126             }
01127             break;
01128         }
01129 
01130         default:
01131             KStyle::drawControl(element, p, widget, r, cg, flags, opt);
01132     }
01133 }
01134 
01135 void HighContrastStyle::drawControlMask (ControlElement element,
01136                                         QPainter *p,
01137                                         const QWidget *w,
01138                                         const QRect &r,
01139                                         const QStyleOption &opt) const
01140 {
01141     switch (element) {
01142         case CE_PushButton:
01143         case CE_ToolBoxTab:
01144         case CE_TabBarTab: 
01145         case CE_ProgressBarLabel:
01146         case CE_TabBarLabel:
01147         case CE_RadioButtonLabel:
01148         case CE_CheckBoxLabel:
01149         case CE_ToolButtonLabel:
01150         case CE_PushButtonLabel: 
01151         case CE_MenuBarEmptyArea:
01152         case CE_MenuBarItem: 
01153         case CE_PopupMenuItem: {
01154             p->fillRect (r, Qt::color0);
01155             break;
01156         }
01157 
01158         default: {
01159             KStyle::drawControlMask (element, p, w, r, opt);
01160         }
01161     }
01162 }
01163 
01164 // Helper to find the next sibling that's not hidden
01165 // Lifted from kstyle.cpp
01166 static Q3ListViewItem* nextVisibleSibling(Q3ListViewItem* item)
01167 {
01168     Q3ListViewItem* sibling = item;
01169     do
01170     {
01171         sibling = sibling->nextSibling();
01172     }
01173     while (sibling && !sibling->isVisible());
01174     
01175     return sibling;
01176 }
01177 
01178 void HighContrastStyle::drawComplexControl (ComplexControl control,
01179                                     QPainter *p,
01180                                     const QWidget *widget,
01181                                     const QRect &r,
01182                                     const QColorGroup &cg,
01183                                     SFlags flags,
01184                                     SCFlags controls,
01185                                     SCFlags active,
01186                                     const QStyleOption& opt ) const
01187 {
01188     if ( widget == hoverWidget )
01189         flags |= Style_MouseOver;
01190 
01191     switch(control)
01192     {
01193         // COMBOBOX
01194         // -------------------------------------------------------------------
01195         case CC_ComboBox: {
01196             setColorsText (p, cg, flags);
01197             drawRoundRect (p, r);
01198             
01199             QRect r2 = QStyle::visualRect (querySubControlMetrics (CC_ComboBox, widget, SC_ComboBoxArrow), widget);
01200             if (flags & Style_HasFocus) {
01201                 QRect r3 (r);
01202                 if (r2.left() > 0)
01203                     r3.setRight (r2.left()+basicLineWidth-1);
01204                 else
01205                     r3.setLeft (r2.right()-basicLineWidth+1);
01206 
01207                 drawPrimitive (PE_FocusRect, p, r3, cg, flags, QStyleOption (p->background().color()));
01208             }
01209             
01210             setColorsButton (p, cg, flags);
01211             // Draw arrow if required
01212             if (controls & SC_ComboBoxArrow) {
01213                 drawRoundRect (p, r2);
01214                 drawArrow (p, r2, PE_ArrowDown, 2*basicLineWidth);
01215             }
01216 
01217             setColorsText (p, cg, flags);
01218             break;
01219         }
01220 
01221         // SPINWIDGET
01222         // -------------------------------------------------------------------
01223         case CC_SpinWidget: {
01224             if (controls & SC_SpinWidgetFrame) {
01225                 setColorsText (p, cg, flags);
01226                 drawRoundRect (p, r);
01227                 if (flags & Style_HasFocus)
01228                     drawPrimitive(PE_FocusRect, p, r, cg, flags, QStyleOption (p->background().color()));
01229             }
01230             
01231             setColorsButton (p, cg, flags);
01232             // Draw arrows if required
01233             if (controls & SC_SpinWidgetDown) {
01234                 QRect r2 = QStyle::visualRect (querySubControlMetrics (CC_SpinWidget, widget, SC_SpinWidgetDown), widget);
01235                 drawRoundRect (p, r2);
01236                 drawArrow (p, r2, PE_SpinWidgetDown, 2*basicLineWidth);
01237             }
01238             if (controls & SC_SpinWidgetUp) {
01239                 QRect r2 = QStyle::visualRect (querySubControlMetrics (CC_SpinWidget, widget, SC_SpinWidgetUp), widget);
01240                 drawRoundRect (p, r2);
01241                 drawArrow (p, r2, PE_SpinWidgetUp, 2*basicLineWidth);
01242             }
01243 
01244             setColorsText (p, cg, flags);
01245             break;
01246         }
01247 
01248         // TOOLBUTTON
01249         // -------------------------------------------------------------------
01250         case CC_ToolButton: {
01251             const QToolButton *toolbutton = (const QToolButton *) widget;
01252 
01253             setColorsButton (p, cg, flags);
01254             p->fillRect (r, p->background().color());
01255 
01256             QRect button, menuarea;
01257             button   = querySubControlMetrics(control, widget, SC_ToolButton, opt);
01258             menuarea = querySubControlMetrics(control, widget, SC_ToolButtonMenu, opt);
01259 
01260             SFlags bflags = flags,
01261                    mflags = flags;
01262 
01263             if (active & SC_ToolButton)
01264                 bflags |= Style_Down;
01265             if (active & SC_ToolButtonMenu)
01266                 mflags |= Style_Down;
01267 
01268             if (controls & SC_ToolButton)
01269             {
01270                 // If we're pressed, on, or raised...
01271                 if (bflags & (Style_Down | Style_On | Style_Raised))
01272                     drawPrimitive(PE_ButtonTool, p, button, cg, bflags, opt);
01273 
01274                 // Check whether to draw a background pixmap
01275                 else if ( toolbutton->parentWidget() &&
01276                           toolbutton->parentWidget()->backgroundPixmap() &&
01277                           !toolbutton->parentWidget()->backgroundPixmap()->isNull() )
01278                 {
01279                     QPixmap pixmap = *(toolbutton->parentWidget()->backgroundPixmap());
01280                     p->drawTiledPixmap( r, pixmap, toolbutton->pos() );
01281                 }
01282             }
01283 
01284             // Draw a toolbutton menu indicator if required
01285             if (controls & SC_ToolButtonMenu)
01286             {
01287                 if (mflags & (Style_Down | Style_On | Style_Raised))
01288                     drawPrimitive(PE_ButtonDropDown, p, menuarea, cg, mflags, opt);
01289                 drawArrow (p, menuarea, PE_ArrowDown);
01290             }
01291 
01292             if (toolbutton->hasFocus() && !toolbutton->focusProxy()) {
01293                 QRect fr = toolbutton->rect();
01294                 addOffset (&fr, 3);
01295                 drawPrimitive(PE_FocusRect, p, fr, cg, flags, QStyleOption (p->background().color()));
01296             }
01297 
01298             break;
01299         }
01300 
01301         // LISTVIEW
01302         // -------------------------------------------------------------------
01303         case CC_ListView: {
01304             /*
01305              * Sigh... Lifted and modified from kstyle.cpp 
01306              */
01307             /* 
01308              * Many thanks to TrollTech AS for donating CC_ListView from QWindowsStyle.
01309              * CC_ListView code is Copyright (C) 1998-2000 TrollTech AS.
01310              */
01311 
01312             // Paint the icon and text.
01313             if ( controls & SC_ListView )
01314                 QCommonStyle::drawComplexControl( control, p, widget, r, cg, flags, controls, active, opt );
01315 
01316             // If we're have a branch or are expanded...
01317             if ( controls & (SC_ListViewBranch | SC_ListViewExpand) )
01318             {
01319                 // If no list view item was supplied, break
01320                 if (opt.isDefault())
01321                     break;
01322 
01323                 Q3ListViewItem *item  = opt.listViewItem();
01324                 Q3ListViewItem *child = item->firstChild();
01325 
01326                 int y = r.y();
01327                 int c;  // dotline vertice count
01328                 int dotoffset = 0;
01329                 Q3PointArray dotlines;
01330 
01331                 if ( active == SC_All && controls == SC_ListViewExpand ) {
01332                     // We only need to draw a vertical line
01333                     c = 2;
01334                     dotlines.resize(2);
01335                     dotlines[0] = QPoint( r.right(), r.top() );
01336                     dotlines[1] = QPoint( r.right(), r.bottom() );
01337 
01338                 } else {
01339 
01340                     int linetop = 0, linebot = 0;
01341                     // each branch needs at most two lines, ie. four end points
01342                     dotoffset = (item->itemPos() + item->height() - y) % 2;
01343                     dotlines.resize( item->childCount() * 4 );
01344                     c = 0;
01345 
01346                     // skip the stuff above the exposed rectangle
01347                     while ( child && y + child->height() <= 0 )
01348                     {
01349                         y += child->totalHeight();
01350                         child = nextVisibleSibling(child);
01351                     }
01352 
01353                     int bx = r.width() / 2;
01354 
01355                     // paint stuff in the magical area
01356                     Q3ListView* v = item->listView();
01357                     int lh = qMax( p->fontMetrics().height() + 2 * v->itemMargin(),
01358                                    QApplication::globalStrut().height() );
01359                     if ( lh % 2 > 0 )
01360                         lh++;
01361 
01362                     // Draw all the expand/close boxes...
01363                     QRect boxrect;
01364                     QStyle::StyleFlags boxflags;
01365                     while ( child && y < r.height() )
01366                     {
01367                         linebot = y + lh/2;
01368                         if ( (child->isExpandable() || child->childCount()) &&
01369                              (child->height() > 0) )
01370                         {
01371                             int h = qMin(lh, 24) - 4*basicLineWidth;
01372                             if (h < 10) 
01373                                 h = 10;
01374                             else 
01375                                 h &= ~1; // Force an even number of pixels
01376             
01377                             // The primitive requires a rect.
01378                             boxrect = QRect( bx-h/2, linebot-h/2, h, h );
01379                             boxflags = child->isOpen() ? QStyle::State_Off : QStyle::State_On;
01380 
01381                             // KStyle extension: Draw the box and expand/collapse indicator
01382                             drawKStylePrimitive( KPE_ListViewExpander, p, NULL, boxrect, cg, boxflags, opt );
01383 
01384                             // dotlinery
01385                             p->setPen( cg.mid() );
01386                             dotlines[c++] = QPoint( bx, linetop );
01387                             dotlines[c++] = QPoint( bx, linebot - 5 );
01388                             dotlines[c++] = QPoint( bx + 5, linebot );
01389                             dotlines[c++] = QPoint( r.width(), linebot );
01390                             linetop = linebot + 5;
01391                         } else {
01392                             // just dotlinery
01393                             dotlines[c++] = QPoint( bx+1, linebot );
01394                             dotlines[c++] = QPoint( r.width(), linebot );
01395                         }
01396 
01397                         y += child->totalHeight();
01398                         child = nextVisibleSibling(child);
01399                     }
01400 
01401                     if ( child ) // there's a child to draw, so move linebot to edge of rectangle
01402                         linebot = r.height();
01403 
01404                     if ( linetop < linebot )
01405                     {
01406                         dotlines[c++] = QPoint( bx, linetop );
01407                         dotlines[c++] = QPoint( bx, linebot );
01408                     }
01409                 }
01410 
01411                 // Draw all the branches...
01412                 static int thickness = kPixelMetric( KPM_ListViewBranchThickness );
01413                 int line; // index into dotlines
01414                 QRect branchrect;
01415                 QStyle::StyleFlags branchflags;
01416                 for( line = 0; line < c; line += 2 )
01417                 {
01418                     // assumptions here: lines are horizontal or vertical.
01419                     // lines always start with the numerically lowest
01420                     // coordinate.
01421 
01422                     // point ... relevant coordinate of current point
01423                     // end ..... same coordinate of the end of the current line
01424                     // other ... the other coordinate of the current point/line
01425                     if ( dotlines[line].y() == dotlines[line+1].y() )
01426                     {
01427                         // Horizontal branch
01428                         int end = dotlines[line+1].x();
01429                         int point = dotlines[line].x();
01430                         int other = dotlines[line].y();
01431 
01432                         branchrect  = QRect( point, other-(thickness/2), end-point, thickness );
01433                         branchflags = QStyle::State_Horizontal;
01434 
01435                         // KStyle extension: Draw the horizontal branch
01436                         drawKStylePrimitive( KPE_ListViewBranch, p, NULL, branchrect, cg, branchflags, opt );
01437 
01438                     } else {
01439                         // Vertical branch
01440                         int end = dotlines[line+1].y();
01441                         int point = dotlines[line].y();
01442                         int other = dotlines[line].x();
01443                         int pixmapoffset = ((point & 1) != dotoffset ) ? 1 : 0;
01444 
01445                         branchrect  = QRect( other-(thickness/2), point, thickness, end-point );
01446                         if (!pixmapoffset)  // ### Hackish - used to hint the offset
01447                             branchflags = QStyle::State_NoChange;
01448                         else
01449                             branchflags = QStyle::State_None;
01450 
01451                         // KStyle extension: Draw the vertical branch
01452                         drawKStylePrimitive( KPE_ListViewBranch, p, NULL, branchrect, cg, branchflags, opt );
01453                     }
01454                 }
01455             }
01456             break;
01457         }
01458 
01459         default:
01460             KStyle::drawComplexControl(control, p, widget,
01461                         r, cg, flags, controls, active, opt);
01462             break;
01463     }
01464 }
01465 
01466 void HighContrastStyle::drawComplexControlMask(ComplexControl c,
01467                                                QPainter *p,
01468                                                const QWidget *w,
01469                                                const QRect &r,
01470                                                const QStyleOption &o) const
01471 {
01472     switch (c) {
01473         case CC_SpinWidget:
01474         case CC_ToolButton:
01475         case CC_ComboBox: {
01476             p->fillRect (r, Qt::color0);
01477             break;
01478         }
01479         default: {
01480             KStyle::drawComplexControlMask (c, p, w, r, o);
01481         }
01482     }
01483 }
01484 
01485 void HighContrastStyle::drawItem( QPainter *p,
01486                                const QRect &r,
01487                                int flags,
01488                                const QColorGroup &cg,
01489                                bool enabled,
01490                                const QPixmap *pixmap,
01491                                const QString &text,
01492                                int len,
01493                                const QColor *penColor ) const
01494 {
01495     p->save();
01496 
01497     // make the disabled things use the cross-line
01498     QFont font = p->font();
01499     font.setStrikeOut (!enabled);
01500     p->setFont (font);
01501     
01502     enabled = true; //do not ghost it in Qt
01503 
01504     KStyle::drawItem (p, r, flags, cg, enabled, pixmap, text, len, penColor);
01505     
01506     p->restore();
01507 }
01508 
01509 QRect HighContrastStyle::querySubControlMetrics( ComplexControl control,
01510                                     const QWidget* widget,
01511                                   SubControl subcontrol,
01512                                   const QStyleOption& opt ) const
01513 {
01514     switch (control)
01515     {
01516         case CC_ComboBox : {
01517             int arrow = pixelMetric (PM_ScrollBarExtent, widget);
01518             switch (subcontrol)
01519             {
01520                 case SC_ComboBoxFrame:
01521                     return QRect (0, 0, widget->width(), widget->height());
01522                 case SC_ComboBoxArrow:
01523                     return QRect (widget->width() - arrow, 0, arrow, widget->height());
01524                 case SC_ComboBoxEditField:
01525                     return QRect (2*basicLineWidth, 2*basicLineWidth,
01526                                 widget->width() - arrow - 3*basicLineWidth, widget->height() - 4*basicLineWidth);
01527     
01528                 default: break;
01529             }
01530             break;
01531         }
01532         case CC_SpinWidget : {
01533             int arrow = pixelMetric (PM_ScrollBarExtent, 0);
01534             switch (subcontrol)
01535             {
01536                 case SC_SpinWidgetFrame:
01537                     return QRect (0, 0, widget->width(), widget->height());
01538                 case SC_SpinWidgetButtonField:
01539                     return QRect (widget->width() - arrow, 0, arrow, widget->height());
01540                 case SC_SpinWidgetUp:
01541                     return QRect (widget->width() - arrow, 0, arrow, widget->height()/2);
01542                 case SC_SpinWidgetDown:
01543                     return QRect (widget->width() - arrow, widget->height()/2,
01544                             arrow, widget->height()-widget->height()/2);
01545                 case SC_SpinWidgetEditField:
01546                     return QRect (2*basicLineWidth, 2*basicLineWidth,
01547                             widget->width() - arrow - 3*basicLineWidth, widget->height() - 4*basicLineWidth);
01548     
01549                 default: break;
01550             }
01551             break;
01552         }
01553 
01554         default: break;
01555     }
01556 
01557     return KStyle::querySubControlMetrics (control, widget, subcontrol, opt);
01558 }
01559 
01560 
01561 int HighContrastStyle::pixelMetric(PixelMetric m, const QWidget *widget) const
01562 {
01563     //### TODO: Use the tab metrics changes from Ker.
01564     switch(m)
01565     {
01566         // BUTTONS
01567         // -------------------------------------------------------------------
01568         case PM_ButtonMargin:               // Space btw. frame and label
01569             return 2*basicLineWidth;
01570 
01571         case PM_ButtonDefaultIndicator: {
01572             if ((widget != 0) && !widget->isEnabled())
01573                 return 0;
01574             else
01575                 return 2*basicLineWidth;
01576         }
01577 
01578         case PM_ButtonShiftHorizontal:
01579         case PM_ButtonShiftVertical:
01580             return 0;
01581 
01582         case PM_ScrollBarExtent: {
01583             int h = 0;
01584             if (widget != 0)
01585                 h = (2*widget->fontMetrics().lineSpacing())/3;
01586             
01587             if (h > 9*basicLineWidth+4)
01588                 return h;
01589             else
01590                 return 9*basicLineWidth+4;
01591         }
01592 
01593         case PM_DefaultFrameWidth: {
01594             if (widget && (widget->inherits ("QLineEdit") || widget->inherits ("QTextEdit")))
01595                 return 2*basicLineWidth;
01596             else 
01597                 return basicLineWidth;
01598         }
01599 
01600         case PM_SpinBoxFrameWidth: {
01601             return 2*basicLineWidth;
01602         }
01603 
01604         case PM_MenuButtonIndicator: {      // Arrow width
01605             int h = 0;
01606             if (widget != 0)
01607                 h = widget->fontMetrics().lineSpacing()/2;
01608             
01609             if (h > 3*basicLineWidth)
01610                 return h;
01611             else
01612                 return 3*basicLineWidth;
01613         }
01614 
01615         // CHECKBOXES / RADIO BUTTONS
01616         // -------------------------------------------------------------------
01617         case PM_ExclusiveIndicatorWidth:    // Radiobutton size
01618         case PM_ExclusiveIndicatorHeight:
01619         case PM_IndicatorWidth:             // Checkbox size
01620         case PM_IndicatorHeight: {
01621             int h = 0;
01622             if (widget != 0)
01623                 h = widget->fontMetrics().lineSpacing()-2*basicLineWidth;
01624             
01625             if (h > 6*basicLineWidth)
01626                 return h;
01627             else
01628                 return 6*basicLineWidth;
01629         }
01630         
01631         case PM_DockWindowSeparatorExtent: {
01632             return 2*basicLineWidth + 1;
01633         }
01634         case PM_DockWindowHandleExtent: {
01635             int w = 0;
01636             if (widget != 0)
01637                 w = widget->fontMetrics().lineSpacing()/4;
01638             if (w > 5*basicLineWidth)
01639                 return w;
01640             else
01641                 return 5*basicLineWidth;
01642         }
01643 
01644         default:
01645             return KStyle::pixelMetric(m, widget);
01646     }
01647 }
01648 
01649 int HighContrastStyle::kPixelMetric( KStylePixelMetric kpm, const QWidget *widget ) const
01650 {
01651     switch (kpm) {
01652         case KPM_ListViewBranchThickness:
01653             // XXX Proper support of thick branches requires reimplementation of
01654             // the drawKStylePrimitive KPE_ListViewBranch case.
01655             return basicLineWidth;
01656         default:
01657             return KStyle::kPixelMetric(kpm, widget);
01658     }
01659 }
01660 
01661 QSize HighContrastStyle::sizeFromContents( ContentsType contents,
01662                                         const QWidget* widget,
01663                                         const QSize &contentSize,
01664                                         const QStyleOption& opt ) const
01665 {
01666     switch (contents)
01667     {
01668         // PUSHBUTTON SIZE
01669         // ------------------------------------------------------------------
01670         case CT_PushButton: {
01671             const QPushButton* button = (const QPushButton*) widget;
01672             int w  = contentSize.width();
01673             int h  = contentSize.height();
01674             int bm = pixelMetric( PM_ButtonMargin, widget );
01675             int fw = pixelMetric( PM_DefaultFrameWidth, widget ) * 2;
01676 
01677             w += bm + fw + 6;   // ### Add 6 to make way for bold font.
01678             h += bm + fw;
01679 
01680             // Ensure we stick to standard width and heights.
01681             if (( button->isDefault() || button->autoDefault() ) && (button->isEnabled())) {
01682                 if ( w < 80 && !button->text().isEmpty() )
01683                     w = 80;
01684 
01685                 // Compensate for default indicator
01686                 int di = pixelMetric( PM_ButtonDefaultIndicator );
01687                 w += di * 2;
01688                 h += di * 2;
01689             }
01690 
01691             if ( h < 22 )
01692                 h = 22;
01693 
01694             return QSize( w + basicLineWidth*2, h + basicLineWidth*2 );
01695         }
01696 
01697         // TOOLBUTTON SIZE
01698         // -----------------------------------------------------------------
01699         case CT_ToolButton: {
01700             int w  = contentSize.width();
01701             int h  = contentSize.height();
01702             return QSize(w + basicLineWidth*2 + 6, h + basicLineWidth*2 + 5);
01703             break;
01704         }
01705 
01706         // COMBOBOX SIZE
01707         // -----------------------------------------------------------------
01708         case CT_ComboBox: {
01709             const QComboBox *cb = static_cast< const QComboBox* > (widget);
01710             int borderSize =  (cb->editable() ? 4 : 2) * basicLineWidth;
01711             int arrowSize = pixelMetric (PM_ScrollBarExtent, cb);
01712             return QSize(borderSize + basicLineWidth + arrowSize, borderSize) + contentSize;
01713         }
01714 
01715         // POPUPMENU ITEM SIZE
01716         // -----------------------------------------------------------------
01717         case CT_PopupMenuItem: {
01718             if ( ! widget || opt.isDefault() )
01719                 return contentSize;
01720 
01721             const QMenu *popup = (const QMenu *) widget;
01722             bool checkable = popup->isCheckable();
01723             QMenuItem *mi = opt.menuItem();
01724             int maxpmw = opt.maxIconWidth();
01725             int w = contentSize.width(), h = contentSize.height();
01726 
01727             if ( mi->custom() ) {
01728                 w = mi->custom()->sizeHint().width();
01729                 h = mi->custom()->sizeHint().height();
01730                 if ( ! mi->custom()->fullSpan() )
01731                     h += 2*itemVMargin + 2*itemFrame;
01732             }
01733             else if ( mi->widget() ) {
01734             } else if ( mi->isSeparator() ) {
01735                 w = 10; // Arbitrary
01736                 h = 4;
01737             }
01738             else {
01739                 if ( mi->pixmap() )
01740                     h = qMax( h, mi->pixmap()->height() + 2*itemFrame );
01741                 else {
01742                     // Ensure that the minimum height for text-only menu items
01743                     // is the same as the icon size used by KDE.
01744                     h = qMax( h, 16 + 2*itemFrame );
01745                     h = qMax( h, popup->fontMetrics().height()
01746                             + 2*itemVMargin + 2*itemFrame );
01747                 }
01748 
01749                 if ( mi->iconSet() && ! mi->iconSet()->isNull() )
01750                     h = qMax( h, mi->iconSet()->pixmap(
01751                                 QIcon::Small, QIcon::Normal).height() +
01752                                 2 * itemFrame );
01753             }
01754 
01755             if ( ! mi->text().isNull() && mi->text().find('\t') >= 0 )
01756                 w += 12;
01757             else if ( mi->popup() )
01758                 w += 2 * arrowHMargin;
01759 
01760             if ( maxpmw )
01761                 w += maxpmw + 6;
01762             if ( checkable && maxpmw < 20 )
01763                 w += 20 - maxpmw;
01764             if ( checkable || maxpmw > 0 )
01765                 w += 12;
01766 
01767             w += rightBorder;
01768 
01769             return QSize( w, h );
01770         }
01771 
01772 
01773         // LINEDIT SIZE
01774         // -----------------------------------------------------------------
01775         case CT_LineEdit: {
01776             return contentSize + QSize (4*basicLineWidth, 4*basicLineWidth);
01777         }
01778 
01779 
01780         default:
01781             return KStyle::sizeFromContents( contents, widget, contentSize, opt );
01782     }
01783 }
01784 
01785 QRect HighContrastStyle::subRect (SubRect subrect, const QWidget * widget) const
01786 {
01787     switch (subrect) {
01788         case SR_ProgressBarGroove:
01789         case SR_ProgressBarContents:
01790         case SR_ProgressBarLabel:
01791             return widget->rect();
01792         default:
01793             return KStyle::subRect (subrect, widget);
01794     }
01795 }
01796 
01797 bool HighContrastStyle::eventFilter (QObject *object, QEvent *event)
01798 {
01799     QWidget* widget = dynamic_cast<QWidget*>(object);
01800     if (widget)
01801     {
01802         // Handle hover effects.
01803         if (event->type() == QEvent::Enter
01804                 && (widget->inherits ("QButton")
01805                     || widget->inherits ("QComboBox")
01806                     || widget->inherits ("QSpinWidget")))
01807         {
01808             hoverWidget = widget;
01809             widget->repaint (false);
01810         }
01811         else if (event->type() == QEvent::Leave
01812                     && (widget->inherits ("QButton")
01813                         || widget->inherits ("QComboBox")
01814                         || widget->inherits ("QSpinWidget")))
01815         {
01816             if (object == hoverWidget)
01817                 hoverWidget = 0L;
01818             widget->repaint (false);
01819         }
01820         // Make sure the focus rectangle is shown correctly.
01821         else if (event->type() == QEvent::FocusIn || event->type() == QEvent::FocusOut)
01822         {
01823             QWidget* widgetparent = dynamic_cast<QWidget*>(widget->parent());
01824             while (widgetparent
01825                             && ! widgetparent->inherits ("QComboBox")
01826                             && ! widgetparent->inherits ("QSpinWidget"))
01827             {
01828                 widgetparent = dynamic_cast<QWidget*>(widgetparent->parent());
01829             }
01830 
01831             if (widgetparent)
01832                 widgetparent->repaint (false);
01833             else
01834                 widget->repaint (false);
01835         }
01836     }
01837     
01838     return KStyle::eventFilter (object, event);
01839 }
01840 
01841 // vim: set noet ts=4 sw=4:
01842 // kate: indent-width 4; replace-tabs off; smart-indent on; tab-width 4;

KStyles

Skip menu "KStyles"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members

API Reference

Skip menu "API Reference"
  • KCMShell
  • KNotify
  • KStyles
  • Nepomuk Daemons
Generated for API Reference by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal