• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • kdefx
 

kdefx

kstyle.cpp
00001 /*
00002  *
00003  * KStyle
00004  * Copyright (C) 2001-2002 Karol Szwed <gallium@kde.org>
00005  *
00006  * TQWindowsStyle CC_ListView and style images were kindly donated by TrollTech,
00007  * Copyright (C) 1998-2000 TrollTech AS.
00008  *
00009  * Many thanks to Bradley T. Hughes for the 3 button scrollbar code.
00010  *
00011  * This library is free software; you can redistribute it and/or
00012  * modify it under the terms of the GNU Library General Public
00013  * License version 2 as published by the Free Software Foundation.
00014  *
00015  * This library is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  * Library General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU Library General Public License
00021  * along with this library; see the file COPYING.LIB.  If not, write to
00022  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00023  * Boston, MA 02110-1301, USA.
00024  */
00025 
00026 #ifdef HAVE_CONFIG_H
00027 #include "config.h"
00028 #endif
00029 
00030 #include "kstyle.h"
00031 
00032 #include <tqapplication.h>
00033 #include <tqbitmap.h>
00034 #include <tqmetaobject.h>
00035 #include <tqcleanuphandler.h>
00036 #include <tqmap.h>
00037 #include <tqimage.h>
00038 #include <tqlistview.h>
00039 #include <tqmenubar.h>
00040 #include <tqpainter.h>
00041 #include <tqpixmap.h>
00042 #include <tqpopupmenu.h>
00043 #include <tqprogressbar.h>
00044 #include <tqscrollbar.h>
00045 #include <tqsettings.h>
00046 #include <tqslider.h>
00047 #include <tqstylefactory.h>
00048 #include <tqtabbar.h>
00049 #include <tqtoolbar.h>
00050 #include <tqframe.h>
00051 
00052 #include <kpixmap.h>
00053 #include <kpixmapeffect.h>
00054 #include <kimageeffect.h>
00055 
00056 #ifdef Q_WS_X11
00057 # include <X11/Xlib.h>
00058 # ifdef HAVE_XRENDER
00059 #  include <X11/extensions/Xrender.h> // schroder
00060    extern bool qt_use_xrender;
00061 # endif
00062 #else
00063 #undef HAVE_XRENDER
00064 #endif
00065 
00066 #ifdef HAVE_XCOMPOSITE
00067 #include <X11/extensions/Xrender.h>
00068 #include <X11/extensions/Xcomposite.h>
00069 #include <dlfcn.h>
00070 #endif
00071 
00072 #include <limits.h>
00073 
00074 namespace
00075 {
00076     // INTERNAL
00077     enum TransparencyEngine {
00078         Disabled = 0,
00079         SoftwareTint,
00080         SoftwareBlend,
00081         XRender
00082     };
00083 
00084     // Drop Shadow
00085     struct ShadowElements {
00086         TQWidget* w1;
00087         TQWidget* w2;
00088     };
00089     typedef TQMap<const TQWidget*,ShadowElements> ShadowMap;
00090         static ShadowMap *_shadowMap = 0;
00091         TQSingleCleanupHandler<ShadowMap> cleanupShadowMap;
00092         ShadowMap &shadowMap() {
00093         if ( !_shadowMap ) {
00094         _shadowMap = new ShadowMap;
00095         cleanupShadowMap.set( &_shadowMap );
00096         }
00097         return *_shadowMap;
00098     }
00099 
00100 
00101     // DO NOT ASK ME HOW I MADE THESE TABLES!
00102     // (I probably won't remember anyway ;)
00103     const double top_right_corner[16] =
00104         { 0.949, 0.965, 0.980, 0.992,
00105           0.851, 0.890, 0.945, 0.980,
00106           0.706, 0.780, 0.890, 0.960,
00107           0.608, 0.706, 0.851, 0.949 };
00108 
00109     const double bottom_right_corner[16] =
00110         { 0.608, 0.706, 0.851, 0.949,
00111           0.706, 0.780, 0.890, 0.960,
00112           0.851, 0.890, 0.945, 0.980,
00113           0.949, 0.965, 0.980, 0.992 };
00114 
00115     const double bottom_left_corner[16] =
00116         { 0.949, 0.851, 0.706, 0.608,
00117           0.965, 0.890, 0.780, 0.706,
00118           0.980, 0.945, 0.890, 0.851,
00119           0.992, 0.980, 0.960, 0.949 };
00120 
00121     const double shadow_strip[4] =
00122         { 0.565, 0.675, 0.835, 0.945 };
00123 
00124     static bool useDropShadow(TQWidget* w)
00125     {
00126         return w && w->metaObject() && 
00127             w->metaObject()->findProperty("KStyleMenuDropShadow") != -1;
00128     }
00129 }
00130 
00131 namespace
00132 {
00133 class TransparencyHandler : public TQObject
00134 {
00135     public:
00136         TransparencyHandler(KStyle* style, TransparencyEngine tEngine,
00137                             float menuOpacity, bool useDropShadow);
00138         ~TransparencyHandler();
00139         bool eventFilter(TQObject* object, TQEvent* event);
00140 
00141     protected:
00142         void blendToColor(const TQColor &col);
00143         void blendToPixmap(const TQColorGroup &cg, const TQWidget* p);
00144 #ifdef HAVE_XRENDER
00145         void XRenderBlendToPixmap(const TQWidget* p);
00146 #endif
00147         bool haveX11RGBASupport();
00148         TQImage handleRealAlpha(TQImage);
00149         void createShadowWindows(const TQWidget* p);
00150         void removeShadowWindows(const TQWidget* p);
00151         void rightShadow(TQImage& dst);
00152         void bottomShadow(TQImage& dst);
00153     private:
00154         bool    dropShadow;
00155         float   opacity;
00156         TQPixmap pix;
00157         KStyle* kstyle;
00158         TransparencyEngine te;
00159 };
00160 } // namespace
00161 
00162 struct KStylePrivate
00163 {
00164     bool  highcolor                : 1;
00165     bool  useFilledFrameWorkaround : 1;
00166     bool  etchDisabledText         : 1;
00167     bool  scrollablePopupmenus     : 1;
00168     bool  menuAltKeyNavigation     : 1;
00169     bool  menuDropShadow           : 1;
00170     bool  sloppySubMenus           : 1;
00171     bool  semiTransparentRubberband : 1;
00172     int   popupMenuDelay;
00173     float menuOpacity;
00174 
00175     TransparencyEngine   transparencyEngine;
00176     KStyle::KStyleScrollBarType  scrollbarType;
00177     TransparencyHandler* menuHandler;
00178     KStyle::KStyleFlags flags;
00179     
00180     //For KPE_ListViewBranch
00181     TQBitmap *verticalLine;
00182     TQBitmap *horizontalLine;
00183 };
00184 
00185 // -----------------------------------------------------------------------------
00186 
00187 
00188 KStyle::KStyle( KStyleFlags flags, KStyleScrollBarType sbtype )
00189     : TQCommonStyle(), d(new KStylePrivate)
00190 {
00191     d->flags = flags;
00192     bool useMenuTransparency    = (flags & AllowMenuTransparency);
00193     d->useFilledFrameWorkaround = (flags & FilledFrameWorkaround);
00194     d->scrollbarType = sbtype;
00195     d->highcolor = TQPixmap::defaultDepth() > 8;
00196 
00197     // Read style settings
00198     TQSettings settings;
00199     d->popupMenuDelay       = settings.readNumEntry ("/KStyle/Settings/PopupMenuDelay", 256);
00200     d->sloppySubMenus       = settings.readBoolEntry("/KStyle/Settings/SloppySubMenus", false);
00201     d->etchDisabledText     = settings.readBoolEntry("/KStyle/Settings/EtchDisabledText", true);
00202     d->menuAltKeyNavigation = settings.readBoolEntry("/KStyle/Settings/MenuAltKeyNavigation", true);
00203     d->scrollablePopupmenus = settings.readBoolEntry("/KStyle/Settings/ScrollablePopupMenus", false);
00204     d->menuDropShadow       = settings.readBoolEntry("/KStyle/Settings/MenuDropShadow", false);
00205     d->semiTransparentRubberband = settings.readBoolEntry("/KStyle/Settings/SemiTransparentRubberband", false);
00206     d->menuHandler = NULL;
00207 
00208     if (useMenuTransparency) {
00209         TQString effectEngine = settings.readEntry("/KStyle/Settings/MenuTransparencyEngine", "Disabled");
00210 
00211 #ifdef HAVE_XRENDER
00212         if (effectEngine == "XRender")
00213             d->transparencyEngine = XRender;
00214 #else
00215         if (effectEngine == "XRender")
00216             d->transparencyEngine = SoftwareBlend;
00217 #endif
00218         else if (effectEngine == "SoftwareBlend")
00219             d->transparencyEngine = SoftwareBlend;
00220         else if (effectEngine == "SoftwareTint")
00221             d->transparencyEngine = SoftwareTint;
00222         else
00223             d->transparencyEngine = Disabled;
00224 
00225         if (d->transparencyEngine != Disabled) {
00226             // Create an instance of the menu transparency handler
00227             d->menuOpacity = settings.readDoubleEntry("/KStyle/Settings/MenuOpacity", 0.90);
00228             d->menuHandler = new TransparencyHandler(this, d->transparencyEngine,
00229                                                      d->menuOpacity, d->menuDropShadow);
00230         }
00231     }
00232     
00233     d->verticalLine   = 0;
00234     d->horizontalLine = 0;
00235 
00236     // Create a transparency handler if only drop shadows are enabled.
00237     if (!d->menuHandler && d->menuDropShadow)
00238         d->menuHandler = new TransparencyHandler(this, Disabled, 1.0, d->menuDropShadow);
00239 }
00240 
00241 
00242 KStyle::~KStyle()
00243 {
00244     delete d->verticalLine;
00245     delete d->horizontalLine;
00246 
00247     delete d->menuHandler;
00248 
00249     d->menuHandler = NULL;
00250     delete d;
00251 }
00252 
00253 
00254 TQString KStyle::defaultStyle()
00255 {
00256     if (TQPixmap::defaultDepth() > 8)
00257        return TQString("plastik");
00258     else
00259        return TQString("light, 3rd revision");
00260 }
00261 
00262 void KStyle::polish( TQWidget* widget )
00263 {
00264     if ( d->useFilledFrameWorkaround )
00265     {
00266         if ( TQFrame *frame = ::tqqt_cast< TQFrame* >( widget ) ) {
00267             TQFrame::Shape shape = frame->frameShape();
00268             if (shape == TQFrame::ToolBarPanel || shape == TQFrame::MenuBarPanel)
00269                 widget->installEventFilter(this);
00270         } 
00271     }
00272     if (widget->isTopLevel())
00273     {
00274         if (!d->menuHandler && useDropShadow(widget))
00275             d->menuHandler = new TransparencyHandler(this, Disabled, 1.0, false);
00276 
00277         if (d->menuHandler && useDropShadow(widget))
00278             widget->installEventFilter(d->menuHandler);
00279     }
00280 }
00281 
00282 
00283 void KStyle::unPolish( TQWidget* widget )
00284 {
00285     if ( d->useFilledFrameWorkaround )
00286     {
00287         if ( TQFrame *frame = ::tqqt_cast< TQFrame* >( widget ) ) {
00288             TQFrame::Shape shape = frame->frameShape();
00289             if (shape == TQFrame::ToolBarPanel || shape == TQFrame::MenuBarPanel)
00290                 widget->removeEventFilter(this);
00291         }
00292     }
00293     if (widget->isTopLevel() && d->menuHandler && useDropShadow(widget))
00294         widget->removeEventFilter(d->menuHandler);
00295 }
00296 
00297 
00298 // Style changes (should) always re-polish popups.
00299 void KStyle::polishPopupMenu( TQPopupMenu* p )
00300 {
00301     if (!p->testWState( WState_Polished ))
00302         p->setCheckable(true);
00303 
00304     // Install transparency handler if the effect is enabled.
00305     if ( d->menuHandler &&
00306         (strcmp(p->name(), "tear off menu") != 0))
00307             p->installEventFilter(d->menuHandler);
00308 }
00309 
00310 
00311 // -----------------------------------------------------------------------------
00312 // KStyle extensions
00313 // -----------------------------------------------------------------------------
00314 
00315 void KStyle::setScrollBarType(KStyleScrollBarType sbtype)
00316 {
00317     d->scrollbarType = sbtype;
00318 }
00319 
00320 KStyle::KStyleFlags KStyle::styleFlags() const
00321 {
00322     return d->flags;
00323 }
00324 
00325 void KStyle::renderMenuBlendPixmap( KPixmap &pix, const TQColorGroup &cg,
00326     const TQPopupMenu* /* popup */ ) const
00327 {
00328     pix.fill(cg.button());  // Just tint as the default behavior
00329 }
00330 
00331 
00332 void KStyle::drawKStylePrimitive( KStylePrimitive kpe,
00333                                   TQPainter* p,
00334                                   const TQWidget* widget,
00335                                   const TQRect &r,
00336                                   const TQColorGroup &cg,
00337                                   SFlags flags,
00338                                   const TQStyleOption& /* opt */ ) const
00339 {
00340     switch( kpe )
00341     {
00342         // Dock / Toolbar / General handles.
00343         // ---------------------------------
00344 
00345         case KPE_DockWindowHandle: {
00346 
00347             // Draws a nice DockWindow handle including the dock title.
00348             TQWidget* wid = const_cast<TQWidget*>(widget);
00349             bool horizontal = flags & Style_Horizontal;
00350             int x,y,w,h,x2,y2;
00351 
00352             r.rect( &x, &y, &w, &h );
00353             if ((w <= 2) || (h <= 2)) {
00354                 p->fillRect(r, cg.highlight());
00355                 return;
00356             }
00357 
00358             
00359             x2 = x + w - 1;
00360             y2 = y + h - 1;
00361 
00362             TQFont fnt;
00363             fnt = TQApplication::font(wid);
00364             fnt.setPointSize( fnt.pointSize()-2 );
00365 
00366             // Draw the item on an off-screen pixmap
00367             // to preserve Xft antialiasing for
00368             // vertically oriented handles.
00369             TQPixmap pix;
00370             if (horizontal)
00371                 pix.resize( h-2, w-2 );
00372             else
00373                 pix.resize( w-2, h-2 );
00374 
00375             TQString title = wid->parentWidget()->caption();
00376             TQPainter p2;
00377             p2.begin(&pix);
00378             p2.fillRect(pix.rect(), cg.brush(TQColorGroup::Highlight));
00379             p2.setPen(cg.highlightedText());
00380             p2.setFont(fnt);
00381             p2.drawText(pix.rect(), AlignCenter, title);
00382             p2.end();
00383 
00384             // Draw a sunken bevel
00385             p->setPen(cg.dark());
00386             p->drawLine(x, y, x2, y);
00387             p->drawLine(x, y, x, y2);
00388             p->setPen(cg.light());
00389             p->drawLine(x+1, y2, x2, y2);
00390             p->drawLine(x2, y+1, x2, y2);
00391 
00392             if (horizontal) {
00393                 TQWMatrix m;
00394                 m.rotate(-90.0);
00395                 TQPixmap vpix = pix.xForm(m);
00396                 bitBlt(wid, r.x()+1, r.y()+1, &vpix);
00397             } else
00398                 bitBlt(wid, r.x()+1, r.y()+1, &pix);
00399 
00400             break;
00401         }
00402 
00403 
00404         /*
00405          * KPE_ListViewExpander and KPE_ListViewBranch are based on code from
00406          * QWindowStyle's CC_ListView, kindly donated by TrollTech.
00407          * CC_ListView code is Copyright (C) 1998-2000 TrollTech AS.
00408          */
00409 
00410         case KPE_ListViewExpander: {
00411             // Typical Windows style expand/collapse element.
00412             int radius = (r.width() - 4) / 2;
00413             int centerx = r.x() + r.width()/2;
00414             int centery = r.y() + r.height()/2;
00415 
00416             // Outer box
00417             p->setPen( cg.mid() );
00418             p->drawRect( r );
00419 
00420             // plus or minus
00421             p->setPen( cg.text() );
00422             p->drawLine( centerx - radius, centery, centerx + radius, centery );
00423             if ( flags & Style_On ) // Collapsed = On
00424                 p->drawLine( centerx, centery - radius, centerx, centery + radius );
00425             break;
00426         }
00427 
00428         case KPE_ListViewBranch: {
00429             // Typical Windows style listview branch element (dotted line).
00430 
00431             // Create the dotline pixmaps if not already created
00432             if ( !d->verticalLine )
00433             {
00434                 // make 128*1 and 1*128 bitmaps that can be used for
00435                 // drawing the right sort of lines.
00436                 d->verticalLine   = new TQBitmap( 1, 129, true );
00437                 d->horizontalLine = new TQBitmap( 128, 1, true );
00438                 TQPointArray a( 64 );
00439                 TQPainter p2;
00440                 p2.begin( d->verticalLine );
00441 
00442                 int i;
00443                 for( i=0; i < 64; i++ )
00444                     a.setPoint( i, 0, i*2+1 );
00445                 p2.setPen( color1 );
00446                 p2.drawPoints( a );
00447                 p2.end();
00448                 TQApplication::flushX();
00449                 d->verticalLine->setMask( *d->verticalLine );
00450 
00451                 p2.begin( d->horizontalLine );
00452                 for( i=0; i < 64; i++ )
00453                     a.setPoint( i, i*2+1, 0 );
00454                 p2.setPen( color1 );
00455                 p2.drawPoints( a );
00456                 p2.end();
00457                 TQApplication::flushX();
00458                 d->horizontalLine->setMask( *d->horizontalLine );
00459             }
00460 
00461             p->setPen( cg.text() );     // cg.dark() is bad for dark color schemes.
00462 
00463             if (flags & Style_Horizontal)
00464             {
00465                 int point = r.x();
00466                 int other = r.y();
00467                 int end = r.x()+r.width();
00468                 int thickness = r.height();
00469 
00470                 while( point < end )
00471                 {
00472                     int i = 128;
00473                     if ( i+point > end )
00474                         i = end-point;
00475                     p->drawPixmap( point, other, *d->horizontalLine, 0, 0, i, thickness );
00476                     point += i;
00477                 }
00478 
00479             } else {
00480                 int point = r.y();
00481                 int other = r.x();
00482                 int end = r.y()+r.height();
00483                 int thickness = r.width();
00484                 int pixmapoffset = (flags & Style_NoChange) ? 0 : 1;    // ### Hackish
00485 
00486                 while( point < end )
00487                 {
00488                     int i = 128;
00489                     if ( i+point > end )
00490                         i = end-point;
00491                     p->drawPixmap( other, point, *d->verticalLine, 0, pixmapoffset, thickness, i );
00492                     point += i;
00493                 }
00494             }
00495 
00496             break;
00497         }
00498 
00499         // Reimplement the other primitives in your styles.
00500         // The current implementation just paints something visibly different.
00501         case KPE_ToolBarHandle:
00502         case KPE_GeneralHandle:
00503         case KPE_SliderHandle:
00504             p->fillRect(r, cg.light());
00505             break;
00506 
00507         case KPE_SliderGroove:
00508             p->fillRect(r, cg.dark());
00509             break;
00510 
00511         default:
00512             p->fillRect(r, Qt::yellow); // Something really bad happened - highlight.
00513             break;
00514     }
00515 }
00516 
00517 
00518 int KStyle::kPixelMetric( KStylePixelMetric kpm, const TQWidget* /* widget */) const
00519 {
00520     int value;
00521     switch(kpm)
00522     {
00523         case KPM_ListViewBranchThickness:
00524             value = 1;
00525             break;
00526 
00527         case KPM_MenuItemSeparatorHeight:
00528         case KPM_MenuItemHMargin:
00529         case KPM_MenuItemVMargin:
00530         case KPM_MenuItemHFrame:
00531         case KPM_MenuItemVFrame:
00532         case KPM_MenuItemCheckMarkHMargin:
00533         case KPM_MenuItemArrowHMargin:
00534         case KPM_MenuItemTabSpacing:
00535         default:
00536             value = 0;
00537     }
00538 
00539     return value;
00540 }
00541 
00542 // -----------------------------------------------------------------------------
00543 
00544 // #ifdef USE_QT4 // kdebindings / smoke needs this function declaration available at all times.  Furthermore I don't think it would hurt to have the declaration available at all times...so leave these commented out for now
00545 
00546 //void KStyle::tqdrawPrimitive( TQ_ControlElement pe,
00547 //                          TQPainter* p,
00548 //                          const TQRect &r,
00549 //                          const TQColorGroup &cg,
00550 //                          SFlags flags,
00551 //                          const TQStyleOption& opt ) const
00552 //{
00553 //  // FIXME:
00554 //  // What should "widget" be in actuality?  How should I get it?  From where?
00555 //  // Almost certainly it should not be null!
00556 //  TQWidget *widget = 0;
00557 //  drawControl(pe, p, widget, r, cg, flags, opt);
00558 //}
00559 
00560 // #endif // USE_QT4
00561 
00562 // -----------------------------------------------------------------------------
00563 
00564 void KStyle::tqdrawPrimitive( TQ_PrimitiveElement pe,
00565                             TQPainter* p,
00566                             const TQRect &r,
00567                             const TQColorGroup &cg,
00568                             SFlags flags,
00569                             const TQStyleOption& opt ) const
00570 {
00571     // TOOLBAR/DOCK WINDOW HANDLE
00572     // ------------------------------------------------------------------------
00573     if (pe == PE_DockWindowHandle)
00574     {
00575         // Wild workarounds are here. Beware.
00576         TQWidget *widget, *parent;
00577 
00578         if (p && p->device()->devType() == TQInternal::Widget) {
00579             widget = static_cast<TQWidget*>(p->device());
00580             parent = widget->parentWidget();
00581         } else
00582             return;     // Don't paint on non-widgets
00583 
00584         // Check if we are a normal toolbar or a hidden dockwidget.
00585         if ( parent &&
00586             (parent->inherits(TQTOOLBAR_OBJECT_NAME_STRING) ||      // Normal toolbar
00587             (parent->inherits(TQMAINWINDOW_OBJECT_NAME_STRING)) ))  // Collapsed dock
00588 
00589             // Draw a toolbar handle
00590             drawKStylePrimitive( KPE_ToolBarHandle, p, widget, r, cg, flags, opt );
00591 
00592         else if ( widget->inherits(TQDOCKWINDOWHANDLE_OBJECT_NAME_STRING) )
00593 
00594             // Draw a dock window handle
00595             drawKStylePrimitive( KPE_DockWindowHandle, p, widget, r, cg, flags, opt );
00596 
00597         else
00598             // General handle, probably a kicker applet handle.
00599             drawKStylePrimitive( KPE_GeneralHandle, p, widget, r, cg, flags, opt );
00600 #if QT_VERSION >= 0x030300
00601 #ifdef HAVE_XRENDER
00602     } else if ( d->semiTransparentRubberband && pe == TQStyle::PE_RubberBand ) {
00603             TQRect rect = r.normalize();
00604             TQPoint point;
00605             point = p->xForm( point );
00606     
00607             static XRenderColor clr = { 0, 0, 0, 0 };
00608             static unsigned long fillColor = 0;
00609             if ( fillColor != cg.highlight().rgb() ) {
00610                 fillColor = cg.highlight().rgb();
00611                 
00612                 unsigned long color = fillColor << 8 | 0x40;
00613 
00614                 int red = (color >> 24) & 0xff;
00615                 int green = (color >> 16) & 0xff;
00616                 int blue = (color >> 8) & 0xff;
00617                 int alpha = (color >> 0) & 0xff;
00618 
00619                 red = red * alpha / 255;
00620                 green = green * alpha / 255;
00621                 blue = blue * alpha / 255;
00622 
00623                 clr.red = (red << 8) + red;
00624                 clr.green = (green << 8) + green;
00625                 clr.blue = (blue << 8) + blue;
00626                 clr.alpha = (alpha << 8) + alpha;
00627             }
00628         
00629             XRenderFillRectangle(
00630                     p->device()->x11Display(),
00631                     PictOpOver,
00632                     p->device()->x11RenderHandle(),
00633                     &clr,
00634                     rect.x() + point.x(),
00635                     rect.y() + point.y(),
00636                     rect.width(),
00637                     rect.height() );
00638 
00639             p->save();
00640             p->setRasterOp( TQt::CopyROP );
00641             p->setPen( TQPen( cg.highlight().dark( 160 ), 1 ) );
00642             p->setBrush( NoBrush );
00643             p->drawRect(
00644                     rect.x() + point.x(),
00645                     rect.y() + point.y(),
00646                     rect.width(),
00647                     rect.height() );
00648             p->restore();
00649 #endif
00650 #endif
00651     } else
00652         TQCommonStyle::tqdrawPrimitive( pe, p, r, cg, flags, opt );
00653 }
00654 
00655 
00656 
00657 void KStyle::drawControl( TQ_ControlElement element,
00658                           TQPainter* p,
00659                           const TQWidget* widget,
00660                           const TQRect &r,
00661                           const TQColorGroup &cg,
00662                           SFlags flags,
00663                           const TQStyleOption &opt ) const
00664 {
00665     switch (element)
00666     {
00667         // TABS
00668         // ------------------------------------------------------------------------
00669         case CE_TabBarTab: {
00670             const TQTabBar* tb  = (const TQTabBar*) widget;
00671             TQTabBar::Shape tbs = tb->shape();
00672             bool selected      = flags & Style_Selected;
00673             int x = r.x(), y=r.y(), bottom=r.bottom(), right=r.right();
00674 
00675             switch (tbs) {
00676 
00677                 case TQTabBar::RoundedAbove: {
00678                     if (!selected)
00679                         p->translate(0,1);
00680                     p->setPen(selected ? cg.light() : cg.shadow());
00681                     p->drawLine(x, y+4, x, bottom);
00682                     p->drawLine(x, y+4, x+4, y);
00683                     p->drawLine(x+4, y, right-1, y);
00684                     if (selected)
00685                         p->setPen(cg.shadow());
00686                     p->drawLine(right, y+1, right, bottom);
00687 
00688                     p->setPen(cg.midlight());
00689                     p->drawLine(x+1, y+4, x+1, bottom);
00690                     p->drawLine(x+1, y+4, x+4, y+1);
00691                     p->drawLine(x+5, y+1, right-2, y+1);
00692 
00693                     if (selected) {
00694                         p->setPen(cg.mid());
00695                         p->drawLine(right-1, y+1, right-1, bottom);
00696                     } else {
00697                         p->setPen(cg.mid());
00698                         p->drawPoint(right-1, y+1);
00699                         p->drawLine(x+4, y+2, right-1, y+2);
00700                         p->drawLine(x+3, y+3, right-1, y+3);
00701                         p->fillRect(x+2, y+4, r.width()-3, r.height()-6, cg.mid());
00702 
00703                         p->setPen(cg.light());
00704                         p->drawLine(x, bottom-1, right, bottom-1);
00705                         p->translate(0,-1);
00706                     }
00707                     break;
00708                 }
00709 
00710                 case TQTabBar::RoundedBelow: {
00711                     if (!selected)
00712                         p->translate(0,-1);
00713                     p->setPen(selected ? cg.light() : cg.shadow());
00714                     p->drawLine(x, bottom-4, x, y);
00715                     if (selected)
00716                         p->setPen(cg.mid());
00717                     p->drawLine(x, bottom-4, x+4, bottom);
00718                     if (selected)
00719                         p->setPen(cg.shadow());
00720                     p->drawLine(x+4, bottom, right-1, bottom);
00721                     p->drawLine(right, bottom-1, right, y);
00722 
00723                     p->setPen(cg.midlight());
00724                     p->drawLine(x+1, bottom-4, x+1, y);
00725                     p->drawLine(x+1, bottom-4, x+4, bottom-1);
00726                     p->drawLine(x+5, bottom-1, right-2, bottom-1);
00727 
00728                     if (selected) {
00729                         p->setPen(cg.mid());
00730                         p->drawLine(right-1, y, right-1, bottom-1);
00731                     } else {
00732                         p->setPen(cg.mid());
00733                         p->drawPoint(right-1, bottom-1);
00734                         p->drawLine(x+4, bottom-2, right-1, bottom-2);
00735                         p->drawLine(x+3, bottom-3, right-1, bottom-3);
00736                         p->fillRect(x+2, y+2, r.width()-3, r.height()-6, cg.mid());
00737                         p->translate(0,1);
00738                         p->setPen(cg.dark());
00739                         p->drawLine(x, y, right, y);
00740                     }
00741                     break;
00742                 }
00743 
00744                 case TQTabBar::TriangularAbove: {
00745                     if (!selected)
00746                         p->translate(0,1);
00747                     p->setPen(selected ? cg.light() : cg.shadow());
00748                     p->drawLine(x, bottom, x, y+6);
00749                     p->drawLine(x, y+6, x+6, y);
00750                     p->drawLine(x+6, y, right-6, y);
00751                     if (selected)
00752                         p->setPen(cg.mid());
00753                     p->drawLine(right-5, y+1, right-1, y+5);
00754                     p->setPen(cg.shadow());
00755                     p->drawLine(right, y+6, right, bottom);
00756 
00757                     p->setPen(cg.midlight());
00758                     p->drawLine(x+1, bottom, x+1, y+6);
00759                     p->drawLine(x+1, y+6, x+6, y+1);
00760                     p->drawLine(x+6, y+1, right-6, y+1);
00761                     p->drawLine(right-5, y+2, right-2, y+5);
00762                     p->setPen(cg.mid());
00763                     p->drawLine(right-1, y+6, right-1, bottom);
00764 
00765                     TQPointArray a(6);
00766                     a.setPoint(0, x+2, bottom);
00767                     a.setPoint(1, x+2, y+7);
00768                     a.setPoint(2, x+7, y+2);
00769                     a.setPoint(3, right-7, y+2);
00770                     a.setPoint(4, right-2, y+7);
00771                     a.setPoint(5, right-2, bottom);
00772                     p->setPen  (selected ? cg.background() : cg.mid());
00773                     p->setBrush(selected ? cg.background() : cg.mid());
00774                     p->drawPolygon(a);
00775                     p->setBrush(NoBrush);
00776                     if (!selected) {
00777                         p->translate(0,-1);
00778                         p->setPen(cg.light());
00779                         p->drawLine(x, bottom, right, bottom);
00780                     }
00781                     break;
00782                 }
00783 
00784                 default: { // TQTabBar::TriangularBelow
00785                     if (!selected)
00786                         p->translate(0,-1);
00787                     p->setPen(selected ? cg.light() : cg.shadow());
00788                     p->drawLine(x, y, x, bottom-6);
00789                     if (selected)
00790                         p->setPen(cg.mid());
00791                     p->drawLine(x, bottom-6, x+6, bottom);
00792                     if (selected)
00793                         p->setPen(cg.shadow());
00794                     p->drawLine(x+6, bottom, right-6, bottom);
00795                     p->drawLine(right-5, bottom-1, right-1, bottom-5);
00796                     if (!selected)
00797                         p->setPen(cg.shadow());
00798                     p->drawLine(right, bottom-6, right, y);
00799 
00800                     p->setPen(cg.midlight());
00801                     p->drawLine(x+1, y, x+1, bottom-6);
00802                     p->drawLine(x+1, bottom-6, x+6, bottom-1);
00803                     p->drawLine(x+6, bottom-1, right-6, bottom-1);
00804                     p->drawLine(right-5, bottom-2, right-2, bottom-5);
00805                     p->setPen(cg.mid());
00806                     p->drawLine(right-1, bottom-6, right-1, y);
00807 
00808                     TQPointArray a(6);
00809                     a.setPoint(0, x+2, y);
00810                     a.setPoint(1, x+2, bottom-7);
00811                     a.setPoint(2, x+7, bottom-2);
00812                     a.setPoint(3, right-7, bottom-2);
00813                     a.setPoint(4, right-2, bottom-7);
00814                     a.setPoint(5, right-2, y);
00815                     p->setPen  (selected ? cg.background() : cg.mid());
00816                     p->setBrush(selected ? cg.background() : cg.mid());
00817                     p->drawPolygon(a);
00818                     p->setBrush(NoBrush);
00819                     if (!selected) {
00820                         p->translate(0,1);
00821                         p->setPen(cg.dark());
00822                         p->drawLine(x, y, right, y);
00823                     }
00824                     break;
00825                 }
00826             };
00827 
00828             break;
00829         }
00830         
00831         // Popup menu scroller
00832         // ------------------------------------------------------------------------
00833         case CE_PopupMenuScroller: {
00834             p->fillRect(r, cg.background());
00835             tqdrawPrimitive(PE_ButtonTool, p, r, cg, Style_Enabled);
00836             tqdrawPrimitive((flags & Style_Up) ? PE_ArrowUp : PE_ArrowDown, p, r, cg, Style_Enabled);
00837             break;
00838         }
00839 
00840 
00841         // PROGRESSBAR
00842         // ------------------------------------------------------------------------
00843         case CE_ProgressBarGroove: {
00844             TQRect fr = subRect(SR_ProgressBarGroove, widget);
00845             tqdrawPrimitive(PE_Panel, p, fr, cg, Style_Sunken, TQStyleOption::SO_Default);
00846             break;
00847         }
00848 
00849         case CE_ProgressBarContents: {
00850             // ### Take into account totalSteps() for busy indicator
00851             const TQProgressBar* pb = (const TQProgressBar*)widget;
00852             TQRect cr = subRect(SR_ProgressBarContents, widget);
00853             double progress = pb->progress();
00854             bool reverse = TQApplication::reverseLayout();
00855             int steps = pb->totalSteps();
00856 
00857             if (!cr.isValid())
00858                 return;
00859 
00860             // Draw progress bar
00861             if (progress > 0 || steps == 0) {
00862                 double pg = (steps == 0) ? 0.1 : progress / steps;
00863                 int width = QMIN(cr.width(), (int)(pg * cr.width()));
00864                 if (steps == 0) { //Busy indicator
00865 
00866                     if (width < 1) width = 1; //A busy indicator with width 0 is kind of useless
00867 
00868                     int remWidth = cr.width() - width; //Never disappear completely
00869                     if (remWidth <= 0) remWidth = 1; //Do something non-crashy when too small...
00870 
00871                     int pstep =  int(progress) % ( 2 *  remWidth );
00872 
00873                     if ( pstep > remWidth ) {
00874                         //Bounce about.. We're remWidth + some delta, we want to be remWidth - delta...
00875                         // - ( (remWidth + some delta) - 2* remWidth )  = - (some deleta - remWidth) = remWidth - some delta..
00876                         pstep = - (pstep - 2 * remWidth );
00877                     }
00878 
00879                     if (reverse)
00880                         p->fillRect(cr.x() + cr.width() - width - pstep, cr.y(), width, cr.height(),
00881                                     cg.brush(TQColorGroup::Highlight));
00882                     else
00883                         p->fillRect(cr.x() + pstep, cr.y(), width, cr.height(),
00884                                     cg.brush(TQColorGroup::Highlight));
00885 
00886                     return;
00887                 }
00888 
00889 
00890                 // Do fancy gradient for highcolor displays
00891                 if (d->highcolor) {
00892                     TQColor c(cg.highlight());
00893                     KPixmap pix;
00894                     pix.resize(cr.width(), cr.height());
00895                     KPixmapEffect::gradient(pix, reverse ? c.light(150) : c.dark(150),
00896                                             reverse ? c.dark(150) : c.light(150),
00897                                             KPixmapEffect::HorizontalGradient);
00898                     if (reverse)
00899                         p->drawPixmap(cr.x()+(cr.width()-width), cr.y(), pix,
00900                                       cr.width()-width, 0, width, cr.height());
00901                     else
00902                         p->drawPixmap(cr.x(), cr.y(), pix, 0, 0, width, cr.height());
00903                 } else
00904                     if (reverse)
00905                         p->fillRect(cr.x()+(cr.width()-width), cr.y(), width, cr.height(),
00906                                     cg.brush(TQColorGroup::Highlight));
00907                     else
00908                         p->fillRect(cr.x(), cr.y(), width, cr.height(),
00909                                     cg.brush(TQColorGroup::Highlight));
00910             }
00911             break;
00912         }
00913 
00914         case CE_ProgressBarLabel: {
00915             const TQProgressBar* pb = (const TQProgressBar*)widget;
00916             TQRect cr = subRect(SR_ProgressBarContents, widget);
00917             double progress = pb->progress();
00918             bool reverse = TQApplication::reverseLayout();
00919             int steps = pb->totalSteps();
00920 
00921             if (!cr.isValid())
00922                 return;
00923 
00924             TQFont font = p->font();
00925             font.setBold(true);
00926             p->setFont(font);
00927 
00928             // Draw label
00929             if (progress > 0 || steps == 0) {
00930                 double pg = (steps == 0) ? 1.0 : progress / steps;
00931                 int width = QMIN(cr.width(), (int)(pg * cr.width()));
00932                 TQRect crect;
00933                 if (reverse)
00934                     crect.setRect(cr.x()+(cr.width()-width), cr.y(), cr.width(), cr.height());
00935                 else
00936                     crect.setRect(cr.x()+width, cr.y(), cr.width(), cr.height());
00937                     
00938                 p->save();
00939                 p->setPen(pb->isEnabled() ? (reverse ? cg.text() : cg.highlightedText()) : cg.text());
00940                 p->drawText(r, AlignCenter, pb->progressString());
00941                 p->setClipRect(crect);
00942                 p->setPen(reverse ? cg.highlightedText() : cg.text());
00943                 p->drawText(r, AlignCenter, pb->progressString());
00944                 p->restore();
00945 
00946             } else {
00947                 p->setPen(cg.text());
00948                 p->drawText(r, AlignCenter, pb->progressString());
00949             }
00950 
00951             break;
00952         }
00953 
00954         default:
00955             TQCommonStyle::drawControl(element, p, widget, r, cg, flags, opt);
00956     }
00957 }
00958 
00959 
00960 TQRect KStyle::subRect(SubRect r, const TQWidget* widget) const
00961 {
00962     switch(r)
00963     {
00964         // KDE2 look smooth progress bar
00965         // ------------------------------------------------------------------------
00966         case SR_ProgressBarGroove:
00967             return widget->rect();
00968 
00969         case SR_ProgressBarContents:
00970         case SR_ProgressBarLabel: {
00971             // ### take into account indicatorFollowsStyle()
00972             TQRect rt = widget->rect();
00973             return TQRect(rt.x()+2, rt.y()+2, rt.width()-4, rt.height()-4);
00974         }
00975 
00976         default:
00977             return TQCommonStyle::subRect(r, widget);
00978     }
00979 }
00980 
00981 
00982 int KStyle::pixelMetric(PixelMetric m, const TQWidget* widget) const
00983 {
00984     switch(m)
00985     {
00986         // BUTTONS
00987         // ------------------------------------------------------------------------
00988         case PM_ButtonShiftHorizontal:      // Offset by 1
00989         case PM_ButtonShiftVertical:        // ### Make configurable
00990             return 1;
00991 
00992         case PM_DockWindowHandleExtent:
00993         {
00994             TQWidget* parent = 0;
00995             // Check that we are not a normal toolbar or a hidden dockwidget,
00996             // in which case we need to adjust the height for font size
00997             if (widget && (parent = widget->parentWidget() )
00998                 && !parent->inherits(TQTOOLBAR_OBJECT_NAME_STRING)
00999                 && !parent->inherits(TQMAINWINDOW_OBJECT_NAME_STRING)
01000                 && widget->inherits(TQDOCKWINDOWHANDLE_OBJECT_NAME_STRING) )
01001                     return widget->fontMetrics().lineSpacing();
01002             else
01003                 return TQCommonStyle::pixelMetric(m, widget);
01004         }
01005 
01006         // TABS
01007         // ------------------------------------------------------------------------
01008         case PM_TabBarTabHSpace:
01009             return 24;
01010 
01011         case PM_TabBarTabVSpace: {
01012             const TQTabBar * tb = (const TQTabBar *) widget;
01013             if ( tb->shape() == TQTabBar::RoundedAbove ||
01014                  tb->shape() == TQTabBar::RoundedBelow )
01015                 return 10;
01016             else
01017                 return 4;
01018         }
01019 
01020         case PM_TabBarTabOverlap: {
01021             const TQTabBar* tb = (const TQTabBar*)widget;
01022             TQTabBar::Shape tbs = tb->shape();
01023 
01024             if ( (tbs == TQTabBar::RoundedAbove) ||
01025                  (tbs == TQTabBar::RoundedBelow) )
01026                 return 0;
01027             else
01028                 return 2;
01029         }
01030 
01031         // SLIDER
01032         // ------------------------------------------------------------------------
01033         case PM_SliderLength:
01034             return 18;
01035 
01036         case PM_SliderThickness:
01037             return 24;
01038 
01039         // Determines how much space to leave for the actual non-tickmark
01040         // portion of the slider.
01041         case PM_SliderControlThickness: {
01042             const TQSlider* slider   = (const TQSlider*)widget;
01043             TQSlider::TickSetting ts = slider->tickmarks();
01044             int thickness = (slider->orientation() == Qt::Horizontal) ?
01045                              slider->height() : slider->width();
01046             switch (ts) {
01047                 case TQSlider::NoMarks:             // Use total area.
01048                     break;
01049                 case TQSlider::Both:
01050                     thickness = (thickness/2) + 3;  // Use approx. 1/2 of area.
01051                     break;
01052                 default:                            // Use approx. 2/3 of area
01053                     thickness = ((thickness*2)/3) + 3;
01054                     break;
01055             };
01056             return thickness;
01057         }
01058 
01059         // SPLITTER
01060         // ------------------------------------------------------------------------
01061         case PM_SplitterWidth:
01062             if (widget && widget->inherits("QDockWindowResizeHandle"))
01063                 return 8;   // ### why do we need 2pix extra?
01064             else
01065                 return 6;
01066 
01067         // FRAMES
01068         // ------------------------------------------------------------------------
01069         case PM_MenuBarFrameWidth:
01070             return 1;
01071 
01072         case PM_DockWindowFrameWidth:
01073             return 1;
01074 
01075         // GENERAL
01076         // ------------------------------------------------------------------------
01077         case PM_MaximumDragDistance:
01078             return -1;
01079 
01080         case PM_MenuBarItemSpacing:
01081             return 5;
01082 
01083         case PM_ToolBarItemSpacing:
01084             return 0;
01085 
01086         case PM_PopupMenuScrollerHeight:
01087             return pixelMetric( PM_ScrollBarExtent, 0);
01088 
01089         default:
01090             return TQCommonStyle::pixelMetric( m, widget );
01091     }
01092 }
01093 
01094 //Helper to find the next sibling that's not hidden
01095 static TQListViewItem* nextVisibleSibling(TQListViewItem* item)
01096 {
01097     TQListViewItem* sibling = item;
01098     do
01099     {
01100         sibling = sibling->nextSibling();
01101     }
01102     while (sibling && !sibling->isVisible());
01103     
01104     return sibling;
01105 }
01106 
01107 void KStyle::drawComplexControl( TQ_ComplexControl control,
01108                                  TQPainter* p,
01109                                  const TQWidget* widget,
01110                                  const TQRect &r,
01111                                  const TQColorGroup &cg,
01112                                  SFlags flags,
01113                                  SCFlags controls,
01114                                  SCFlags active,
01115                                  const TQStyleOption &opt ) const
01116 {
01117     switch(control)
01118     {
01119         // 3 BUTTON SCROLLBAR
01120         // ------------------------------------------------------------------------
01121         case CC_ScrollBar: {
01122             // Many thanks to Brad Hughes for contributing this code.
01123             bool useThreeButtonScrollBar = (d->scrollbarType & ThreeButtonScrollBar);
01124 
01125             const TQScrollBar *sb = (const TQScrollBar*)widget;
01126             bool   maxedOut   = (sb->minValue()    == sb->maxValue());
01127             bool   horizontal = (sb->orientation() == Qt::Horizontal);
01128             SFlags sflags     = ((horizontal ? Style_Horizontal : Style_Default) |
01129                                  (maxedOut   ? Style_Default : Style_Enabled));
01130 
01131             TQRect  addline, subline, subline2, addpage, subpage, slider, first, last;
01132             subline = querySubControlMetrics(control, widget, SC_ScrollBarSubLine, opt);
01133             addline = querySubControlMetrics(control, widget, SC_ScrollBarAddLine, opt);
01134             subpage = querySubControlMetrics(control, widget, SC_ScrollBarSubPage, opt);
01135             addpage = querySubControlMetrics(control, widget, SC_ScrollBarAddPage, opt);
01136             slider  = querySubControlMetrics(control, widget, SC_ScrollBarSlider,  opt);
01137             first   = querySubControlMetrics(control, widget, SC_ScrollBarFirst,   opt);
01138             last    = querySubControlMetrics(control, widget, SC_ScrollBarLast,    opt);
01139             subline2 = addline;
01140 
01141             if ( useThreeButtonScrollBar )
01142                 if (horizontal)
01143                     subline2.moveBy(-addline.width(), 0);
01144                 else
01145                     subline2.moveBy(0, -addline.height());
01146 
01147             // Draw the up/left button set
01148             if ((controls & SC_ScrollBarSubLine) && subline.isValid()) {
01149                 tqdrawPrimitive(PE_ScrollBarSubLine, p, subline, cg,
01150                             sflags | (active == SC_ScrollBarSubLine ?
01151                                 Style_Down : Style_Default));
01152 
01153                 if (useThreeButtonScrollBar && subline2.isValid())
01154                     tqdrawPrimitive(PE_ScrollBarSubLine, p, subline2, cg,
01155                             sflags | (active == SC_ScrollBarSubLine ?
01156                                 Style_Down : Style_Default));
01157             }
01158 
01159             if ((controls & SC_ScrollBarAddLine) && addline.isValid())
01160                 tqdrawPrimitive(PE_ScrollBarAddLine, p, addline, cg,
01161                             sflags | ((active == SC_ScrollBarAddLine) ?
01162                                         Style_Down : Style_Default));
01163 
01164             if ((controls & SC_ScrollBarSubPage) && subpage.isValid())
01165                 tqdrawPrimitive(PE_ScrollBarSubPage, p, subpage, cg,
01166                             sflags | ((active == SC_ScrollBarSubPage) ?
01167                                         Style_Down : Style_Default));
01168 
01169             if ((controls & SC_ScrollBarAddPage) && addpage.isValid())
01170                 tqdrawPrimitive(PE_ScrollBarAddPage, p, addpage, cg,
01171                             sflags | ((active == SC_ScrollBarAddPage) ?
01172                                         Style_Down : Style_Default));
01173 
01174             if ((controls & SC_ScrollBarFirst) && first.isValid())
01175                 tqdrawPrimitive(PE_ScrollBarFirst, p, first, cg,
01176                             sflags | ((active == SC_ScrollBarFirst) ?
01177                                         Style_Down : Style_Default));
01178 
01179             if ((controls & SC_ScrollBarLast) && last.isValid())
01180                 tqdrawPrimitive(PE_ScrollBarLast, p, last, cg,
01181                             sflags | ((active == SC_ScrollBarLast) ?
01182                                         Style_Down : Style_Default));
01183 
01184             if ((controls & SC_ScrollBarSlider) && slider.isValid()) {
01185                 tqdrawPrimitive(PE_ScrollBarSlider, p, slider, cg,
01186                             sflags | ((active == SC_ScrollBarSlider) ?
01187                                         Style_Down : Style_Default));
01188                 // Draw focus rect
01189                 if (sb->hasFocus()) {
01190                     TQRect fr(slider.x() + 2, slider.y() + 2,
01191                              slider.width() - 5, slider.height() - 5);
01192                     tqdrawPrimitive(PE_FocusRect, p, fr, cg, Style_Default);
01193                 }
01194             }
01195             break;
01196         }
01197 
01198 
01199         // SLIDER
01200         // -------------------------------------------------------------------
01201         case CC_Slider: {
01202             const TQSlider* slider = (const TQSlider*)widget;
01203             TQRect groove = querySubControlMetrics(CC_Slider, widget, SC_SliderGroove, opt);
01204             TQRect handle = querySubControlMetrics(CC_Slider, widget, SC_SliderHandle, opt);
01205 
01206             // Double-buffer slider for no flicker
01207             TQPixmap pix(widget->size());
01208             TQPainter p2;
01209             p2.begin(&pix);
01210 
01211             if ( slider->parentWidget() &&
01212                  slider->parentWidget()->backgroundPixmap() &&
01213                  !slider->parentWidget()->backgroundPixmap()->isNull() ) {
01214                 TQPixmap pixmap = *(slider->parentWidget()->backgroundPixmap());
01215                 p2.drawTiledPixmap(r, pixmap, slider->pos());
01216             } else
01217                 pix.fill(cg.background());
01218 
01219             // Draw slider groove
01220             if ((controls & SC_SliderGroove) && groove.isValid()) {
01221                 drawKStylePrimitive( KPE_SliderGroove, &p2, widget, groove, cg, flags, opt );
01222 
01223                 // Draw the focus rect around the groove
01224                 if (slider->hasFocus())
01225                     tqdrawPrimitive(PE_FocusRect, &p2, groove, cg);
01226             }
01227 
01228             // Draw the tickmarks
01229             if (controls & SC_SliderTickmarks)
01230                 TQCommonStyle::drawComplexControl(control, &p2, widget,
01231                         r, cg, flags, SC_SliderTickmarks, active, opt);
01232 
01233             // Draw the slider handle
01234             if ((controls & SC_SliderHandle) && handle.isValid()) {
01235                 if (active == SC_SliderHandle)
01236                     flags |= Style_Active;
01237                 drawKStylePrimitive( KPE_SliderHandle, &p2, widget, handle, cg, flags, opt );
01238             }
01239 
01240             p2.end();
01241             bitBlt((TQWidget*)widget, r.x(), r.y(), &pix);
01242             break;
01243         }
01244 
01245         // LISTVIEW
01246         // -------------------------------------------------------------------
01247         case CC_ListView: {
01248 
01249             /*
01250              * Many thanks to TrollTech AS for donating CC_ListView from TQWindowsStyle.
01251              * CC_ListView code is Copyright (C) 1998-2000 TrollTech AS.
01252              */
01253 
01254             // Paint the icon and text.
01255             if ( controls & SC_ListView )
01256                 TQCommonStyle::drawComplexControl( control, p, widget, r, cg, flags, controls, active, opt );
01257 
01258             // If we're have a branch or are expanded...
01259             if ( controls & (SC_ListViewBranch | SC_ListViewExpand) )
01260             {
01261                 // If no list view item was supplied, break
01262                 if (opt.isDefault())
01263                     break;
01264 
01265                 TQListViewItem *item  = opt.listViewItem();
01266                 TQListViewItem *child = item->firstChild();
01267 
01268                 int y = r.y();
01269                 int c;  // dotline vertice count
01270                 int dotoffset = 0;
01271                 TQPointArray dotlines;
01272 
01273                 if ( active == SC_All && controls == SC_ListViewExpand ) {
01274                     // We only need to draw a vertical line
01275                     c = 2;
01276                     dotlines.resize(2);
01277                     dotlines[0] = TQPoint( r.right(), r.top() );
01278                     dotlines[1] = TQPoint( r.right(), r.bottom() );
01279 
01280                 } else {
01281 
01282                     int linetop = 0, linebot = 0;
01283                     // each branch needs at most two lines, ie. four end points
01284                     dotoffset = (item->itemPos() + item->height() - y) % 2;
01285                     dotlines.resize( item->childCount() * 4 );
01286                     c = 0;
01287 
01288                     // skip the stuff above the exposed rectangle
01289                     while ( child && y + child->height() <= 0 )
01290                     {
01291                         y += child->totalHeight();
01292                         child = nextVisibleSibling(child);
01293                     }
01294 
01295                     int bx = r.width() / 2;
01296 
01297                     // paint stuff in the magical area
01298                     TQListView* v = item->listView();
01299                     int lh = QMAX( p->fontMetrics().height() + 2 * v->itemMargin(),
01300                                    TQApplication::globalStrut().height() );
01301                     if ( lh % 2 > 0 )
01302                         lh++;
01303 
01304                     // Draw all the expand/close boxes...
01305                     TQRect boxrect;
01306                     TQStyle::StyleFlags boxflags;
01307                     while ( child && y < r.height() )
01308                     {
01309                         linebot = y + lh/2;
01310                         if ( (child->isExpandable() || child->childCount()) &&
01311                              (child->height() > 0) )
01312                         {
01313                             // The primitive requires a rect.
01314                             boxrect = TQRect( bx-4, linebot-4, 9, 9 );
01315                             boxflags = child->isOpen() ? TQStyle::Style_Off : TQStyle::Style_On;
01316 
01317                             // KStyle extension: Draw the box and expand/collapse indicator
01318                             drawKStylePrimitive( KPE_ListViewExpander, p, NULL, boxrect, cg, boxflags, opt );
01319 
01320                             // dotlinery
01321                             p->setPen( cg.mid() );
01322                             dotlines[c++] = TQPoint( bx, linetop );
01323                             dotlines[c++] = TQPoint( bx, linebot - 5 );
01324                             dotlines[c++] = TQPoint( bx + 5, linebot );
01325                             dotlines[c++] = TQPoint( r.width(), linebot );
01326                             linetop = linebot + 5;
01327                         } else {
01328                             // just dotlinery
01329                             dotlines[c++] = TQPoint( bx+1, linebot );
01330                             dotlines[c++] = TQPoint( r.width(), linebot );
01331                         }
01332 
01333                         y += child->totalHeight();
01334                         child = nextVisibleSibling(child);
01335                     }
01336 
01337                     if ( child ) // there's a child to draw, so move linebot to edge of rectangle
01338                         linebot = r.height();
01339 
01340                     if ( linetop < linebot )
01341                     {
01342                         dotlines[c++] = TQPoint( bx, linetop );
01343                         dotlines[c++] = TQPoint( bx, linebot );
01344                     }
01345                 }
01346 
01347                 // Draw all the branches...
01348                 static int thickness = kPixelMetric( KPM_ListViewBranchThickness );
01349                 int line; // index into dotlines
01350                 TQRect branchrect;
01351                 TQStyle::StyleFlags branchflags;
01352                 for( line = 0; line < c; line += 2 )
01353                 {
01354                     // assumptions here: lines are horizontal or vertical.
01355                     // lines always start with the numerically lowest
01356                     // coordinate.
01357 
01358                     // point ... relevant coordinate of current point
01359                     // end ..... same coordinate of the end of the current line
01360                     // other ... the other coordinate of the current point/line
01361                     if ( dotlines[line].y() == dotlines[line+1].y() )
01362                     {
01363                         // Horizontal branch
01364                         int end = dotlines[line+1].x();
01365                         int point = dotlines[line].x();
01366                         int other = dotlines[line].y();
01367 
01368                         branchrect  = TQRect( point, other-(thickness/2), end-point, thickness );
01369                         branchflags = TQStyle::Style_Horizontal;
01370 
01371                         // KStyle extension: Draw the horizontal branch
01372                         drawKStylePrimitive( KPE_ListViewBranch, p, NULL, branchrect, cg, branchflags, opt );
01373 
01374                     } else {
01375                         // Vertical branch
01376                         int end = dotlines[line+1].y();
01377                         int point = dotlines[line].y();
01378                         int other = dotlines[line].x();
01379                         int pixmapoffset = ((point & 1) != dotoffset ) ? 1 : 0;
01380 
01381                         branchrect  = TQRect( other-(thickness/2), point, thickness, end-point );
01382                         if (!pixmapoffset)  // ### Hackish - used to hint the offset
01383                             branchflags = TQStyle::Style_NoChange;
01384                         else
01385                             branchflags = TQStyle::Style_Default;
01386 
01387                         // KStyle extension: Draw the vertical branch
01388                         drawKStylePrimitive( KPE_ListViewBranch, p, NULL, branchrect, cg, branchflags, opt );
01389                     }
01390                 }
01391             }
01392             break;
01393         }
01394 
01395         default:
01396             TQCommonStyle::drawComplexControl( control, p, widget, r, cg,
01397                                               flags, controls, active, opt );
01398             break;
01399     }
01400 }
01401 
01402 
01403 TQStyle::SubControl KStyle::querySubControl( TQ_ComplexControl control,
01404                                             const TQWidget* widget,
01405                                             const TQPoint &pos,
01406                                             const TQStyleOption &opt ) const
01407 {
01408     TQStyle::SubControl ret = TQCommonStyle::querySubControl(control, widget, pos, opt);
01409 
01410     if (d->scrollbarType == ThreeButtonScrollBar) {
01411         // Enable third button
01412         if (control == CC_ScrollBar && ret == SC_None)
01413             ret = SC_ScrollBarSubLine;
01414     }
01415     return ret;
01416 }
01417 
01418 
01419 TQRect KStyle::querySubControlMetrics( TQ_ComplexControl control,
01420                                       const TQWidget* widget,
01421                                       SubControl sc,
01422                                       const TQStyleOption &opt ) const
01423 {
01424     TQRect ret;
01425 
01426     if (control == CC_ScrollBar)
01427     {
01428         bool threeButtonScrollBar = d->scrollbarType & ThreeButtonScrollBar;
01429         bool platinumScrollBar    = d->scrollbarType & PlatinumStyleScrollBar;
01430         bool nextScrollBar        = d->scrollbarType & NextStyleScrollBar;
01431 
01432         const TQScrollBar *sb = (const TQScrollBar*)widget;
01433         bool horizontal = sb->orientation() == Qt::Horizontal;
01434         int sliderstart = sb->sliderStart();
01435         int sbextent    = pixelMetric(PM_ScrollBarExtent, widget);
01436         int maxlen      = (horizontal ? sb->width() : sb->height())
01437                           - (sbextent * (threeButtonScrollBar ? 3 : 2));
01438         int sliderlen;
01439 
01440         // calculate slider length
01441         if (sb->maxValue() != sb->minValue())
01442         {
01443             uint range = sb->maxValue() - sb->minValue();
01444             sliderlen = (sb->pageStep() * maxlen) / (range + sb->pageStep());
01445 
01446             int slidermin = pixelMetric( PM_ScrollBarSliderMin, widget );
01447             if ( sliderlen < slidermin || range > INT_MAX / 2 )
01448                 sliderlen = slidermin;
01449             if ( sliderlen > maxlen )
01450                 sliderlen = maxlen;
01451         } else
01452             sliderlen = maxlen;
01453 
01454         // Subcontrols
01455         switch (sc)
01456         {
01457             case SC_ScrollBarSubLine: {
01458                 // top/left button
01459                 if (platinumScrollBar) {
01460                     if (horizontal)
01461                         ret.setRect(sb->width() - 2 * sbextent, 0, sbextent, sbextent);
01462                     else
01463                         ret.setRect(0, sb->height() - 2 * sbextent, sbextent, sbextent);
01464                 } else
01465                     ret.setRect(0, 0, sbextent, sbextent);
01466                 break;
01467             }
01468 
01469             case SC_ScrollBarAddLine: {
01470                 // bottom/right button
01471                 if (nextScrollBar) {
01472                     if (horizontal)
01473                         ret.setRect(sbextent, 0, sbextent, sbextent);
01474                     else
01475                         ret.setRect(0, sbextent, sbextent, sbextent);
01476                 } else {
01477                     if (horizontal)
01478                         ret.setRect(sb->width() - sbextent, 0, sbextent, sbextent);
01479                     else
01480                         ret.setRect(0, sb->height() - sbextent, sbextent, sbextent);
01481                 }
01482                 break;
01483             }
01484 
01485             case SC_ScrollBarSubPage: {
01486                 // between top/left button and slider
01487                 if (platinumScrollBar) {
01488                     if (horizontal)
01489                         ret.setRect(0, 0, sliderstart, sbextent);
01490                     else
01491                         ret.setRect(0, 0, sbextent, sliderstart);
01492                 } else if (nextScrollBar) {
01493                     if (horizontal)
01494                         ret.setRect(sbextent*2, 0, sliderstart-2*sbextent, sbextent);
01495                     else
01496                         ret.setRect(0, sbextent*2, sbextent, sliderstart-2*sbextent);
01497                 } else {
01498                     if (horizontal)
01499                         ret.setRect(sbextent, 0, sliderstart - sbextent, sbextent);
01500                     else
01501                         ret.setRect(0, sbextent, sbextent, sliderstart - sbextent);
01502                 }
01503                 break;
01504             }
01505 
01506             case SC_ScrollBarAddPage: {
01507                 // between bottom/right button and slider
01508                 int fudge;
01509 
01510                 if (platinumScrollBar)
01511                     fudge = 0;
01512                 else if (nextScrollBar)
01513                     fudge = 2*sbextent;
01514                 else
01515                     fudge = sbextent;
01516 
01517                 if (horizontal)
01518                     ret.setRect(sliderstart + sliderlen, 0,
01519                             maxlen - sliderstart - sliderlen + fudge, sbextent);
01520                 else
01521                     ret.setRect(0, sliderstart + sliderlen, sbextent,
01522                             maxlen - sliderstart - sliderlen + fudge);
01523                 break;
01524             }
01525 
01526             case SC_ScrollBarGroove: {
01527                 int multi = threeButtonScrollBar ? 3 : 2;
01528                 int fudge;
01529 
01530                 if (platinumScrollBar)
01531                     fudge = 0;
01532                 else if (nextScrollBar)
01533                     fudge = 2*sbextent;
01534                 else
01535                     fudge = sbextent;
01536 
01537                 if (horizontal)
01538                     ret.setRect(fudge, 0, sb->width() - sbextent * multi, sb->height());
01539                 else
01540                     ret.setRect(0, fudge, sb->width(), sb->height() - sbextent * multi);
01541                 break;
01542             }
01543 
01544             case SC_ScrollBarSlider: {
01545                 if (horizontal)
01546                     ret.setRect(sliderstart, 0, sliderlen, sbextent);
01547                 else
01548                     ret.setRect(0, sliderstart, sbextent, sliderlen);
01549                 break;
01550             }
01551 
01552             default:
01553                 ret = TQCommonStyle::querySubControlMetrics(control, widget, sc, opt);
01554                 break;
01555         }
01556     } else
01557         ret = TQCommonStyle::querySubControlMetrics(control, widget, sc, opt);
01558 
01559     return ret;
01560 }
01561 
01562 static const char * const kstyle_close_xpm[] = {
01563 "12 12 2 1",
01564 "# c #000000",
01565 ". c None",
01566 "............",
01567 "............",
01568 "..##....##..",
01569 "...##..##...",
01570 "....####....",
01571 ".....##.....",
01572 "....####....",
01573 "...##..##...",
01574 "..##....##..",
01575 "............",
01576 "............",
01577 "............"};
01578 
01579 static const char * const kstyle_maximize_xpm[]={
01580 "12 12 2 1",
01581 "# c #000000",
01582 ". c None",
01583 "............",
01584 "............",
01585 ".##########.",
01586 ".##########.",
01587 ".#........#.",
01588 ".#........#.",
01589 ".#........#.",
01590 ".#........#.",
01591 ".#........#.",
01592 ".#........#.",
01593 ".##########.",
01594 "............"};
01595 
01596 
01597 static const char * const kstyle_minimize_xpm[] = {
01598 "12 12 2 1",
01599 "# c #000000",
01600 ". c None",
01601 "............",
01602 "............",
01603 "............",
01604 "............",
01605 "............",
01606 "............",
01607 "............",
01608 "...######...",
01609 "...######...",
01610 "............",
01611 "............",
01612 "............"};
01613 
01614 static const char * const kstyle_normalizeup_xpm[] = {
01615 "12 12 2 1",
01616 "# c #000000",
01617 ". c None",
01618 "............",
01619 "...#######..",
01620 "...#######..",
01621 "...#.....#..",
01622 ".#######.#..",
01623 ".#######.#..",
01624 ".#.....#.#..",
01625 ".#.....###..",
01626 ".#.....#....",
01627 ".#.....#....",
01628 ".#######....",
01629 "............"};
01630 
01631 
01632 static const char * const kstyle_shade_xpm[] = {
01633 "12 12 2 1",
01634 "# c #000000",
01635 ". c None",
01636 "............",
01637 "............",
01638 "............",
01639 "............",
01640 "............",
01641 ".....#......",
01642 "....###.....",
01643 "...#####....",
01644 "..#######...",
01645 "............",
01646 "............",
01647 "............"};
01648 
01649 static const char * const kstyle_unshade_xpm[] = {
01650 "12 12 2 1",
01651 "# c #000000",
01652 ". c None",
01653 "............",
01654 "............",
01655 "............",
01656 "............",
01657 "..#######...",
01658 "...#####....",
01659 "....###.....",
01660 ".....#......",
01661 "............",
01662 "............",
01663 "............",
01664 "............"};
01665 
01666 static const char * const dock_window_close_xpm[] = {
01667 "8 8 2 1",
01668 "# c #000000",
01669 ". c None",
01670 "##....##",
01671 ".##..##.",
01672 "..####..",
01673 "...##...",
01674 "..####..",
01675 ".##..##.",
01676 "##....##",
01677 "........"};
01678 
01679 // Message box icons, from page 210 of the Windows style guide.
01680 
01681 // Hand-drawn to resemble Microsoft's icons, but in the Mac/Netscape
01682 // palette.  The "question mark" icon, which Microsoft recommends not
01683 // using but a lot of people still use, is left out.
01684 
01685 /* XPM */
01686 static const char * const information_xpm[]={
01687 "32 32 5 1",
01688 ". c None",
01689 "c c #000000",
01690 "* c #999999",
01691 "a c #ffffff",
01692 "b c #0000ff",
01693 "...........********.............",
01694 "........***aaaaaaaa***..........",
01695 "......**aaaaaaaaaaaaaa**........",
01696 ".....*aaaaaaaaaaaaaaaaaa*.......",
01697 "....*aaaaaaaabbbbaaaaaaaac......",
01698 "...*aaaaaaaabbbbbbaaaaaaaac.....",
01699 "..*aaaaaaaaabbbbbbaaaaaaaaac....",
01700 ".*aaaaaaaaaaabbbbaaaaaaaaaaac...",
01701 ".*aaaaaaaaaaaaaaaaaaaaaaaaaac*..",
01702 "*aaaaaaaaaaaaaaaaaaaaaaaaaaaac*.",
01703 "*aaaaaaaaaabbbbbbbaaaaaaaaaaac*.",
01704 "*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
01705 "*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
01706 "*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
01707 "*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
01708 "*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
01709 ".*aaaaaaaaaaabbbbbaaaaaaaaaac***",
01710 ".*aaaaaaaaaaabbbbbaaaaaaaaaac***",
01711 "..*aaaaaaaaaabbbbbaaaaaaaaac***.",
01712 "...caaaaaaabbbbbbbbbaaaaaac****.",
01713 "....caaaaaaaaaaaaaaaaaaaac****..",
01714 ".....caaaaaaaaaaaaaaaaaac****...",
01715 "......ccaaaaaaaaaaaaaacc****....",
01716 ".......*cccaaaaaaaaccc*****.....",
01717 "........***cccaaaac*******......",
01718 "..........****caaac*****........",
01719 ".............*caaac**...........",
01720 "...............caac**...........",
01721 "................cac**...........",
01722 ".................cc**...........",
01723 "..................***...........",
01724 "...................**..........."};
01725 /* XPM */
01726 static const char* const warning_xpm[]={
01727 "32 32 4 1",
01728 ". c None",
01729 "a c #ffff00",
01730 "* c #000000",
01731 "b c #999999",
01732 ".............***................",
01733 "............*aaa*...............",
01734 "...........*aaaaa*b.............",
01735 "...........*aaaaa*bb............",
01736 "..........*aaaaaaa*bb...........",
01737 "..........*aaaaaaa*bb...........",
01738 ".........*aaaaaaaaa*bb..........",
01739 ".........*aaaaaaaaa*bb..........",
01740 "........*aaaaaaaaaaa*bb.........",
01741 "........*aaaa***aaaa*bb.........",
01742 ".......*aaaa*****aaaa*bb........",
01743 ".......*aaaa*****aaaa*bb........",
01744 "......*aaaaa*****aaaaa*bb.......",
01745 "......*aaaaa*****aaaaa*bb.......",
01746 ".....*aaaaaa*****aaaaaa*bb......",
01747 ".....*aaaaaa*****aaaaaa*bb......",
01748 "....*aaaaaaaa***aaaaaaaa*bb.....",
01749 "....*aaaaaaaa***aaaaaaaa*bb.....",
01750 "...*aaaaaaaaa***aaaaaaaaa*bb....",
01751 "...*aaaaaaaaaa*aaaaaaaaaa*bb....",
01752 "..*aaaaaaaaaaa*aaaaaaaaaaa*bb...",
01753 "..*aaaaaaaaaaaaaaaaaaaaaaa*bb...",
01754 ".*aaaaaaaaaaaa**aaaaaaaaaaa*bb..",
01755 ".*aaaaaaaaaaa****aaaaaaaaaa*bb..",
01756 "*aaaaaaaaaaaa****aaaaaaaaaaa*bb.",
01757 "*aaaaaaaaaaaaa**aaaaaaaaaaaa*bb.",
01758 "*aaaaaaaaaaaaaaaaaaaaaaaaaaa*bbb",
01759 "*aaaaaaaaaaaaaaaaaaaaaaaaaaa*bbb",
01760 ".*aaaaaaaaaaaaaaaaaaaaaaaaa*bbbb",
01761 "..*************************bbbbb",
01762 "....bbbbbbbbbbbbbbbbbbbbbbbbbbb.",
01763 ".....bbbbbbbbbbbbbbbbbbbbbbbbb.."};
01764 /* XPM */
01765 static const char* const critical_xpm[]={
01766 "32 32 4 1",
01767 ". c None",
01768 "a c #999999",
01769 "* c #ff0000",
01770 "b c #ffffff",
01771 "...........********.............",
01772 ".........************...........",
01773 ".......****************.........",
01774 "......******************........",
01775 ".....********************a......",
01776 "....**********************a.....",
01777 "...************************a....",
01778 "..*******b**********b*******a...",
01779 "..******bbb********bbb******a...",
01780 ".******bbbbb******bbbbb******a..",
01781 ".*******bbbbb****bbbbb*******a..",
01782 "*********bbbbb**bbbbb*********a.",
01783 "**********bbbbbbbbbb**********a.",
01784 "***********bbbbbbbb***********aa",
01785 "************bbbbbb************aa",
01786 "************bbbbbb************aa",
01787 "***********bbbbbbbb***********aa",
01788 "**********bbbbbbbbbb**********aa",
01789 "*********bbbbb**bbbbb*********aa",
01790 ".*******bbbbb****bbbbb*******aa.",
01791 ".******bbbbb******bbbbb******aa.",
01792 "..******bbb********bbb******aaa.",
01793 "..*******b**********b*******aa..",
01794 "...************************aaa..",
01795 "....**********************aaa...",
01796 "....a********************aaa....",
01797 ".....a******************aaa.....",
01798 "......a****************aaa......",
01799 ".......aa************aaaa.......",
01800 ".........aa********aaaaa........",
01801 "...........aaaaaaaaaaa..........",
01802 ".............aaaaaaa............"};
01803 
01804 TQPixmap KStyle::stylePixmap( StylePixmap stylepixmap,
01805                           const TQWidget* widget,
01806                           const TQStyleOption& opt) const
01807 {
01808     switch (stylepixmap) {
01809         case SP_TitleBarShadeButton:
01810             return TQPixmap(const_cast<const char**>(kstyle_shade_xpm));
01811         case SP_TitleBarUnshadeButton:
01812             return TQPixmap(const_cast<const char**>(kstyle_unshade_xpm));
01813         case SP_TitleBarNormalButton:
01814             return TQPixmap(const_cast<const char**>(kstyle_normalizeup_xpm));
01815         case SP_TitleBarMinButton:
01816             return TQPixmap(const_cast<const char**>(kstyle_minimize_xpm));
01817         case SP_TitleBarMaxButton:
01818             return TQPixmap(const_cast<const char**>(kstyle_maximize_xpm));
01819         case SP_TitleBarCloseButton:
01820             return TQPixmap(const_cast<const char**>(kstyle_close_xpm));
01821         case SP_DockWindowCloseButton:
01822             return TQPixmap(const_cast<const char**>(dock_window_close_xpm ));
01823         case SP_MessageBoxInformation:
01824             return TQPixmap(const_cast<const char**>(information_xpm));
01825         case SP_MessageBoxWarning:
01826             return TQPixmap(const_cast<const char**>(warning_xpm));
01827         case SP_MessageBoxCritical:
01828             return TQPixmap(const_cast<const char**>(critical_xpm));
01829         default:
01830             break;
01831     }
01832     return TQCommonStyle::stylePixmap(stylepixmap, widget, opt);
01833 }
01834 
01835 
01836 int KStyle::styleHint( TQ_StyleHint sh, const TQWidget* w,
01837                        const TQStyleOption &opt, TQStyleHintReturn* shr) const
01838 {
01839     switch (sh)
01840     {
01841         case SH_EtchDisabledText:
01842             return d->etchDisabledText ? 1 : 0;
01843 
01844         case SH_PopupMenu_Scrollable:
01845             return d->scrollablePopupmenus ? 1 : 0;
01846 
01847         case SH_MenuBar_AltKeyNavigation:
01848             return d->menuAltKeyNavigation ? 1 : 0;
01849 
01850         case SH_PopupMenu_SubMenuPopupDelay:
01851             if ( styleHint( SH_PopupMenu_SloppySubMenus, w ) )
01852                 return QMIN( 100, d->popupMenuDelay );
01853             else
01854                 return d->popupMenuDelay;
01855 
01856         case SH_PopupMenu_SloppySubMenus:
01857             return d->sloppySubMenus;
01858 
01859         case SH_ItemView_ChangeHighlightOnFocus:
01860         case SH_Slider_SloppyKeyEvents:
01861         case SH_MainWindow_SpaceBelowMenuBar:
01862         case SH_PopupMenu_AllowActiveAndDisabled:
01863             return 0;
01864 
01865         case SH_Slider_SnapToValue:
01866         case SH_PrintDialog_RightAlignButtons:
01867         case SH_FontDialog_SelectAssociatedText:
01868         case SH_MenuBar_MouseTracking:
01869         case SH_PopupMenu_MouseTracking:
01870         case SH_ComboBox_ListMouseTracking:
01871         case SH_ScrollBar_MiddleClickAbsolutePosition:
01872             return 1;
01873         case SH_LineEdit_PasswordCharacter:
01874         {
01875             if (w) {
01876                 const TQFontMetrics &fm = w->fontMetrics();
01877                 if (fm.inFont(TQChar(0x25CF))) {
01878                     return 0x25CF;
01879                 } else if (fm.inFont(TQChar(0x2022))) {
01880                     return 0x2022;
01881                 }
01882             }
01883             return '*';
01884         }
01885 
01886         default:
01887             return TQCommonStyle::styleHint(sh, w, opt, shr);
01888     }
01889 }
01890 
01891 
01892 bool KStyle::eventFilter( TQObject* object, TQEvent* event )
01893 {
01894     if ( d->useFilledFrameWorkaround )
01895     {
01896         // Make the QMenuBar/TQToolBar paintEvent() cover a larger area to
01897         // ensure that the filled frame contents are properly painted.
01898         // We essentially modify the paintEvent's rect to include the
01899         // panel border, which also paints the widget's interior.
01900         // This is nasty, but I see no other way to properly repaint
01901         // filled frames in all QMenuBars and QToolBars.
01902         // -- Karol.
01903         TQFrame *frame = 0;
01904         if ( event->type() == TQEvent::Paint
01905                 && (frame = ::tqqt_cast<TQFrame*>(object)) )
01906         {
01907             if (frame->frameShape() != TQFrame::ToolBarPanel && frame->frameShape() != TQFrame::MenuBarPanel)
01908                 return false;
01909                 
01910             bool horizontal = true;
01911             TQPaintEvent* pe = (TQPaintEvent*)event;
01912             TQToolBar *toolbar = ::tqqt_cast< TQToolBar *>( frame );
01913             TQRect r = pe->rect();
01914 
01915             if (toolbar && toolbar->orientation() == Qt::Vertical)
01916                 horizontal = false;
01917 
01918             if (horizontal) {
01919                 if ( r.height() == frame->height() )
01920                     return false;   // Let TQFrame handle the painting now.
01921 
01922                 // Else, send a new paint event with an updated paint rect.
01923                 TQPaintEvent dummyPE( TQRect( r.x(), 0, r.width(), frame->height()) );
01924                 TQApplication::sendEvent( frame, &dummyPE );
01925             }
01926             else {  // Vertical
01927                 if ( r.width() == frame->width() )
01928                     return false;
01929 
01930                 TQPaintEvent dummyPE( TQRect( 0, r.y(), frame->width(), r.height()) );
01931                 TQApplication::sendEvent( frame, &dummyPE );
01932             }
01933 
01934             // Discard this event as we sent a new paintEvent.
01935             return true;
01936         }
01937     }
01938 
01939     return false;
01940 }
01941 
01942 
01943 // -----------------------------------------------------------------------------
01944 // I N T E R N A L -  KStyle menu transparency handler
01945 // -----------------------------------------------------------------------------
01946 
01947 TransparencyHandler::TransparencyHandler( KStyle* style,
01948     TransparencyEngine tEngine, float menuOpacity, bool useDropShadow )
01949     : TQObject()
01950 {
01951     te = tEngine;
01952     kstyle = style;
01953     opacity = menuOpacity;
01954     dropShadow = useDropShadow;
01955     pix.setOptimization(TQPixmap::BestOptim);
01956 }
01957 
01958 TransparencyHandler::~TransparencyHandler()
01959 {
01960 }
01961 
01962 bool TransparencyHandler::haveX11RGBASupport()
01963 {
01964     // Simple way to determine if we have ARGB support
01965     if (TQPaintDevice::x11AppDepth() == 32) {
01966         return true;
01967     }
01968     else {
01969         return false;
01970     }
01971 }
01972 
01973 #define REAL_ALPHA_STRENGTH 255.0
01974 
01975 // This is meant to be ugly but fast.
01976 void TransparencyHandler::rightShadow(TQImage& dst)
01977 {
01978     bool have_composite = haveX11RGBASupport();
01979 
01980     if (dst.depth() != 32)
01981         dst = dst.convertDepth(32);
01982 
01983     // blend top-right corner.
01984     int pixels = dst.width() * dst.height();
01985 #ifdef WORDS_BIGENDIAN
01986     unsigned char* data = dst.bits() + 1;   // Skip alpha
01987 #else
01988     unsigned char* data = dst.bits();       // Skip alpha
01989 #endif
01990     for(int i = 0; i < 16; i++) {
01991         if (have_composite) {
01992             data++;
01993             data++;
01994             data++;
01995             *data = (unsigned char)(REAL_ALPHA_STRENGTH*(1.0-top_right_corner[i])); data++;
01996         }
01997         else {
01998             *data = (unsigned char)((*data)*top_right_corner[i]); data++;
01999             *data = (unsigned char)((*data)*top_right_corner[i]); data++;
02000             *data = (unsigned char)((*data)*top_right_corner[i]); data++;
02001             data++; // skip alpha
02002         }
02003     }
02004 
02005     pixels -= 32;   // tint right strip without rounded edges.
02006     int c = 0;
02007     for(int i = 0; i < pixels; i++) {
02008         if (have_composite) {
02009             data++;
02010             data++;
02011             data++;;
02012             *data = (unsigned char)(REAL_ALPHA_STRENGTH*(1.0-shadow_strip[c])); data++;
02013         }
02014         else {
02015             *data = (unsigned char)((*data)*shadow_strip[c]); data++;
02016             *data = (unsigned char)((*data)*shadow_strip[c]); data++;
02017             *data = (unsigned char)((*data)*shadow_strip[c]); data++;
02018             data++; // skip alpha
02019         }
02020         ++c;
02021         c %= 4;
02022     }
02023 
02024     // tint bottom edge
02025     for(int i = 0; i < 16; i++) {
02026         if (have_composite) {
02027             data++;
02028             data++;
02029             data++;
02030             *data = (unsigned char)(REAL_ALPHA_STRENGTH*(1.0-bottom_right_corner[i])); data++;
02031         }
02032         else {
02033             *data = (unsigned char)((*data)*bottom_right_corner[i]); data++;
02034             *data = (unsigned char)((*data)*bottom_right_corner[i]); data++;
02035             *data = (unsigned char)((*data)*bottom_right_corner[i]); data++;
02036             data++; // skip alpha
02037         }
02038     }
02039 }
02040 
02041 void TransparencyHandler::bottomShadow(TQImage& dst)
02042 {
02043     bool have_composite = haveX11RGBASupport();
02044 
02045     if (dst.depth() != 32)
02046         dst = dst.convertDepth(32);
02047 
02048     int line = 0;
02049     int width = dst.width() - 4;
02050     double strip_data = shadow_strip[0];
02051     double* corner = const_cast<double*>(bottom_left_corner);
02052 
02053 #ifdef WORDS_BIGENDIAN
02054     unsigned char* data = dst.bits() + 1;   // Skip alpha
02055 #else
02056     unsigned char* data = dst.bits();   // Skip alpha
02057 #endif
02058 
02059     for(int y = 0; y < 4; y++)
02060     {
02061         // Bottom-left Corner
02062         for(int x = 0; x < 4; x++) {
02063             if (have_composite) {
02064                 data++;
02065                 data++;
02066                 data++;
02067                 *data = (unsigned char)(REAL_ALPHA_STRENGTH*(1.0-(*corner))); data++;
02068             }
02069             else {
02070                 *data = (unsigned char)((*data)*(*corner)); data++;
02071                 *data = (unsigned char)((*data)*(*corner)); data++;
02072                 *data = (unsigned char)((*data)*(*corner)); data++;
02073                 data++; // skip alpha
02074             }
02075             corner++;
02076         }
02077 
02078         // Scanline
02079         for(int x = 0; x < width; x++) {
02080             if (have_composite) {
02081                 data++;
02082                 data++;
02083                 data++;
02084                 *data = (unsigned char)(REAL_ALPHA_STRENGTH*(1.0-strip_data)); data++;
02085             }
02086             else {
02087                 *data = (unsigned char)((*data)*strip_data); data++;
02088                 *data = (unsigned char)((*data)*strip_data); data++;
02089                 *data = (unsigned char)((*data)*strip_data); data++;
02090                 data++; // skip alpha
02091             }
02092         }
02093 
02094         strip_data = shadow_strip[line++];
02095     }
02096 }
02097 
02098 TQImage TransparencyHandler::handleRealAlpha(TQImage img) {
02099     TQImage clearImage = img.convertDepth(32);
02100     clearImage.setAlphaBuffer(true);
02101 
02102     int w = clearImage.width();
02103     int h = clearImage.height();
02104 
02105     for (int y = 0; y < h; ++y) {
02106         TQRgb *ls = (TQRgb *)clearImage.scanLine( y );
02107         for (int x = 0; x < w; ++x) {
02108             TQRgb l = ls[x];
02109             ls[x] = tqRgba( 0, 0, 0, 0 );
02110         }
02111     }
02112 
02113     return clearImage;
02114 }
02115 
02116 // Create a shadow of thickness 4.
02117 void TransparencyHandler::createShadowWindows(const TQWidget* p)
02118 {
02119 #ifdef Q_WS_X11
02120     int x2 = p->x()+p->width();
02121     int y2 = p->y()+p->height();
02122     TQRect shadow1(x2, p->y() + 4, 4, p->height());
02123     TQRect shadow2(p->x() + 4, y2, p->width() - 4, 4);
02124 
02125     bool have_composite = haveX11RGBASupport();
02126 
02127     // Create a fake drop-down shadow effect via blended Xwindows
02128     ShadowElements se;
02129     se.w1 = new TQWidget(0, 0, (WFlags)(WStyle_Customize | WType_Popup | WX11BypassWM) );
02130     se.w2 = new TQWidget(0, 0, (WFlags)(WStyle_Customize | WType_Popup | WX11BypassWM) );
02131     se.w1->setGeometry(shadow1);
02132     se.w2->setGeometry(shadow2);
02133     XSelectInput(qt_xdisplay(), se.w1->winId(), StructureNotifyMask );
02134     XSelectInput(qt_xdisplay(), se.w2->winId(), StructureNotifyMask );
02135 
02136     // Insert a new ShadowMap entry
02137     shadowMap()[p] = se;
02138 
02139     // Some hocus-pocus here to create the drop-shadow.
02140     TQPixmap pix_shadow1;
02141     TQPixmap pix_shadow2;
02142     if (have_composite) {
02143         pix_shadow1 = TQPixmap(shadow1.width(), shadow1.height());
02144         pix_shadow2 = TQPixmap(shadow2.width(), shadow2.height());
02145     }
02146     else {
02147         pix_shadow1 = TQPixmap::grabWindow(qt_xrootwin(),
02148                 shadow1.x(), shadow1.y(), shadow1.width(), shadow1.height());
02149         pix_shadow2 = TQPixmap::grabWindow(qt_xrootwin(),
02150                 shadow2.x(), shadow2.y(), shadow2.width(), shadow2.height());
02151     }
02152 
02153     TQImage img;
02154     img = pix_shadow1.convertToImage();
02155     if (have_composite) img = handleRealAlpha(img);
02156     rightShadow(img);
02157     pix_shadow1.convertFromImage(img);
02158     img = pix_shadow2.convertToImage();
02159     if (have_composite) img = handleRealAlpha(img);
02160     bottomShadow(img);
02161     pix_shadow2.convertFromImage(img);
02162 
02163     // Set the background pixmaps
02164     se.w1->setErasePixmap(pix_shadow1);
02165     se.w2->setErasePixmap(pix_shadow2);
02166 
02167     // Show the 'shadow' just before showing the popup menu window
02168     // Don't use TQWidget::show() so we don't confuse QEffects, thus causing broken focus.
02169     XMapWindow(qt_xdisplay(), se.w1->winId());
02170     XMapWindow(qt_xdisplay(), se.w2->winId());
02171 #else
02172     Q_UNUSED( p )
02173 #endif
02174 }
02175 
02176 void TransparencyHandler::removeShadowWindows(const TQWidget* p)
02177 {
02178 #ifdef Q_WS_X11
02179     ShadowMap::iterator it = shadowMap().find(p);
02180     if (it != shadowMap().end())
02181     {
02182         ShadowElements se = it.data();
02183         XUnmapWindow(qt_xdisplay(), se.w1->winId());    // hide
02184         XUnmapWindow(qt_xdisplay(), se.w2->winId());
02185         XFlush(qt_xdisplay());                          // try to hide faster
02186         delete se.w1;
02187         delete se.w2;
02188         shadowMap().erase(it);
02189     }
02190 #else
02191     Q_UNUSED( p )
02192 #endif
02193 }
02194 
02195 bool TransparencyHandler::eventFilter( TQObject* object, TQEvent* event )
02196 {
02197 #if !defined Q_WS_MAC && !defined Q_WS_WIN
02198     // Transparency idea was borrowed from KDE2's "MegaGradient" Style,
02199     // Copyright (C) 2000 Daniel M. Duley <mosfet@kde.org>
02200 
02201     // Added 'fake' menu shadows <04-Jul-2002> -- Karol
02202     TQWidget* p = (TQWidget*)object;
02203     TQEvent::Type et = event->type();
02204 
02205     if (et == TQEvent::Show)
02206     {
02207         // Handle translucency
02208         if (te != Disabled)
02209         {
02210             pix = TQPixmap::grabWindow(qt_xrootwin(),
02211                     p->x(), p->y(), p->width(), p->height());
02212 
02213             switch (te) {
02214 #ifdef HAVE_XRENDER
02215                 case XRender:
02216                     if (qt_use_xrender) {
02217                         XRenderBlendToPixmap(p);
02218                         break;
02219                     }
02220                     // Fall through intended
02221 #else
02222                 case XRender:
02223 #endif
02224                 case SoftwareBlend:
02225                     blendToPixmap(p->colorGroup(), p);
02226                     break;
02227 
02228                 case SoftwareTint:
02229                 default:
02230                     blendToColor(p->colorGroup().button());
02231             };
02232 
02233             p->setErasePixmap(pix);
02234         }
02235 
02236         // Handle drop shadow
02237         // * FIXME : !shadowMap().contains(p) is a workaround for leftover
02238         // * shadows after duplicate show events.
02239         // * TODO : determine real cause for duplicate events
02240         // * till 20021005
02241         if ((dropShadow  || useDropShadow(p))
02242             && p->width() > 16 && p->height() > 16 && !shadowMap().contains( p ))
02243             createShadowWindows(p);
02244     }
02245         else if (et == TQEvent::Resize && p->isShown() && p->isTopLevel())
02246         {
02247         // Handle drop shadow
02248         if (dropShadow || useDropShadow(p))
02249         {
02250             removeShadowWindows(p);
02251             createShadowWindows(p);
02252         }
02253         }
02254     else if (et == TQEvent::Hide)
02255     {
02256         // Handle drop shadow
02257         if (dropShadow || useDropShadow(p))
02258             removeShadowWindows(p);
02259 
02260         // Handle translucency
02261         if (te != Disabled)
02262             p->setErasePixmap(TQPixmap());
02263     }
02264 
02265 #endif
02266     return false;
02267 }
02268 
02269 
02270 // Blends a TQImage to a predefined color, with a given opacity.
02271 void TransparencyHandler::blendToColor(const TQColor &col)
02272 {
02273     if (opacity < 0.0 || opacity > 1.0)
02274         return;
02275 
02276     TQImage img = pix.convertToImage();
02277     KImageEffect::blend(col, img, opacity);
02278     pix.convertFromImage(img);
02279 }
02280 
02281 
02282 void TransparencyHandler::blendToPixmap(const TQColorGroup &cg, const TQWidget* p)
02283 {
02284     if (opacity < 0.0 || opacity > 1.0)
02285         return;
02286 
02287     KPixmap blendPix;
02288     blendPix.resize( pix.width(), pix.height() );
02289 
02290     if (blendPix.width()  != pix.width() ||
02291         blendPix.height() != pix.height())
02292         return;
02293 
02294     // Allow styles to define the blend pixmap - allows for some interesting effects.
02295     if (::tqqt_cast<TQPopupMenu*>(p))
02296         kstyle->renderMenuBlendPixmap( blendPix, cg, ::tqqt_cast<TQPopupMenu*>(p) );
02297     else
02298         blendPix.fill(cg.button()); // Just tint as the default behavior
02299 
02300     TQImage blendImg = blendPix.convertToImage();
02301     TQImage backImg  = pix.convertToImage();
02302     KImageEffect::blend(blendImg, backImg, opacity);
02303     pix.convertFromImage(backImg);
02304 }
02305 
02306 
02307 #ifdef HAVE_XRENDER
02308 // Here we go, use XRender in all its glory.
02309 // NOTE: This is actually a bit slower than the above routines
02310 // on non-accelerated displays. -- Karol.
02311 void TransparencyHandler::XRenderBlendToPixmap(const TQWidget* p)
02312 {
02313     KPixmap renderPix;
02314     renderPix.resize( pix.width(), pix.height() );
02315 
02316     // Allow styles to define the blend pixmap - allows for some interesting effects.
02317     if (::tqqt_cast<TQPopupMenu*>(p))
02318        kstyle->renderMenuBlendPixmap( renderPix, p->colorGroup(),
02319                ::tqqt_cast<TQPopupMenu*>(p) );
02320     else
02321         renderPix.fill(p->colorGroup().button());   // Just tint as the default behavior
02322 
02323     Display* dpy = qt_xdisplay();
02324     Pixmap   alphaPixmap;
02325     Picture  alphaPicture;
02326     XRenderPictFormat        Rpf;
02327     XRenderPictureAttributes Rpa;
02328     XRenderColor clr;
02329     clr.alpha = ((unsigned short)(255*opacity) << 8);
02330 
02331     Rpf.type  = PictTypeDirect;
02332     Rpf.depth = 8;
02333     Rpf.direct.alphaMask = 0xff;
02334     Rpa.repeat = True;  // Tile
02335 
02336     XRenderPictFormat* xformat = XRenderFindFormat(dpy,
02337         PictFormatType | PictFormatDepth | PictFormatAlphaMask, &Rpf, 0);
02338 
02339     alphaPixmap = XCreatePixmap(dpy, p->handle(), 1, 1, 8);
02340     alphaPicture = XRenderCreatePicture(dpy, alphaPixmap, xformat, CPRepeat, &Rpa);
02341 
02342     XRenderFillRectangle(dpy, PictOpSrc, alphaPicture, &clr, 0, 0, 1, 1);
02343 
02344     XRenderComposite(dpy, PictOpOver,
02345             renderPix.x11RenderHandle(), alphaPicture, pix.x11RenderHandle(), // src, mask, dst
02346             0, 0,   // srcx,  srcy
02347             0, 0,   // maskx, masky
02348             0, 0,   // dstx,  dsty
02349             pix.width(), pix.height());
02350 
02351     XRenderFreePicture(dpy, alphaPicture);
02352     XFreePixmap(dpy, alphaPixmap);
02353 }
02354 #endif
02355 
02356 void KStyle::virtual_hook( int, void* )
02357 { /*BASE::virtual_hook( id, data );*/ }
02358 
02359 // HACK for gtk-qt-engine
02360 
02361 extern "C" KDE_EXPORT
02362 void kde_kstyle_set_scrollbar_type_windows( void* style )
02363 {
02364     ((KStyle*)style)->setScrollBarType( KStyle::WindowsStyleScrollBar );
02365 }
02366 
02367 // vim: set noet ts=4 sw=4:
02368 // kate: indent-width 4; replace-tabs off; tab-width 4; space-indent off;
02369 
02370 #include "kstyle.moc"

kdefx

Skip menu "kdefx"
  • Main Page
  • Alphabetical List
  • Class List
  • File List
  • Class Members

kdefx

Skip menu "kdefx"
  • arts
  • dcop
  • dnssd
  • interfaces
  •     interface
  •     library
  •   kspeech
  •   ktexteditor
  • kabc
  • kate
  • kcmshell
  • kdecore
  • kded
  • kdefx
  • kdeprint
  • kdesu
  • kdeui
  • kdoctools
  • khtml
  • kimgio
  • kinit
  • kio
  •   bookmarks
  •   httpfilter
  •   kfile
  •   kio
  •   kioexec
  •   kpasswdserver
  •   kssl
  • kioslave
  •   http
  • kjs
  • kmdi
  •   kmdi
  • knewstuff
  • kparts
  • krandr
  • kresources
  • kspell2
  • kunittest
  • kutils
  • kwallet
  • libkmid
  • libkscreensaver
Generated for kdefx by doxygen 1.7.6.1
This website is maintained by Timothy Pearson.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. |