home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / qt3_emx.zip / examples / themes / metal.cpp < prev    next >
C/C++ Source or Header  |  2001-10-11  |  12KB  |  483 lines

  1. /****************************************************************************
  2. ** $Id:  qt/metal.cpp   3.0.0   edited Aug 10 17:22 $
  3. **
  4. ** Copyright (C) 1992-2000 Trolltech AS.  All rights reserved.
  5. **
  6. ** This file is part of an example program for Qt.  This example
  7. ** program may be used, distributed and modified without limitation.
  8. **
  9. *****************************************************************************/
  10.  
  11. #include "metal.h"
  12. #include "qapplication.h"
  13. #include "qcombobox.h"
  14. #include "qpainter.h"
  15. #include "qdrawutil.h" // for now
  16. #include "qpixmap.h" // for now
  17. #include "qpalette.h" // for now
  18. #include "qwidget.h"
  19. #include "qlabel.h"
  20. #include "qimage.h"
  21. #include "qpushbutton.h"
  22. #include "qwidget.h"
  23. #include "qrangecontrol.h"
  24. #include "qscrollbar.h"
  25. #include "qslider.h"
  26. #include <limits.h>
  27.  
  28.  
  29. /////////////////////////////////////////////////////////
  30. #include "stonedark.xpm"
  31. #include "stone1.xpm"
  32. #include "marble.xpm"
  33. ///////////////////////////////////////////////////////
  34.  
  35.  
  36.  
  37. MetalStyle::MetalStyle() : QWindowsStyle() { }
  38.  
  39. /*!
  40.   Reimplementation from QStyle
  41.  */
  42. void MetalStyle::polish( QApplication *app)
  43. {
  44.     oldPalette = app->palette();
  45.  
  46.     // we simply create a nice QColorGroup with a couple of fancy
  47.     // pixmaps here and apply to it all widgets
  48.  
  49.     QFont f("times", app->font().pointSize() );
  50.     f.setBold( TRUE );
  51.     f.setItalic( TRUE );
  52.     app->setFont( f, TRUE, "QMenuBar");
  53.     app->setFont( f, TRUE, "QPopupMenu");
  54.  
  55.  
  56.  
  57.     //    QPixmap button( stonedark_xpm );
  58.  
  59.     QColor gold("#B9B9A5A54040"); //same as topgrad below
  60.     QPixmap button( 1, 1 ); button.fill( gold );
  61.  
  62.     QPixmap background(marble_xpm);
  63.     QPixmap dark( 1, 1 ); dark.fill( red.dark() );
  64.     QPixmap mid( stone1_xpm );
  65.     QPixmap light( stone1_xpm );//1, 1 ); light.fill( green );
  66.  
  67.     QPalette op = app->palette();
  68.  
  69.     QColor backCol( 227,227,227 );
  70.  
  71.     // QPalette op(white);
  72.     QColorGroup active (op.active().foreground(),
  73.              QBrush(op.active().button(),button),
  74.              QBrush(op.active().light(), light),
  75.              QBrush(op.active().dark(), dark),
  76.              QBrush(op.active().mid(), mid),
  77.              op.active().text(),
  78.              Qt::white,
  79.              op.active().base(),//             QColor(236,182,120),
  80.              QBrush(backCol, background)
  81.              );
  82.     active.setColor( QColorGroup::ButtonText,  Qt::white  );
  83.     active.setColor( QColorGroup::Shadow,  Qt::black  );
  84.     QColorGroup disabled (op.disabled().foreground(),
  85.              QBrush(op.disabled().button(),button),
  86.              QBrush(op.disabled().light(), light),
  87.              op.disabled().dark(),
  88.              QBrush(op.disabled().mid(), mid),
  89.              op.disabled().text(),
  90.              Qt::white,
  91.              op.disabled().base(),//             QColor(236,182,120),
  92.              QBrush(backCol, background)
  93.              );
  94.  
  95.     QPalette newPalette( active, disabled, active );
  96.     app->setPalette( newPalette, TRUE );
  97. }
  98.  
  99. /*!
  100.   Reimplementation from QStyle
  101.  */
  102. void MetalStyle::unPolish( QApplication *app)
  103. {
  104.     app->setPalette(oldPalette, TRUE);
  105.     app->setFont( app->font(), TRUE );
  106. }
  107.  
  108. /*!
  109.   Reimplementation from QStyle
  110.  */
  111. void MetalStyle::polish( QWidget* w)
  112. {
  113.  
  114.    // the polish function sets some widgets to transparent mode and
  115.     // some to translate background mode in order to get the full
  116.     // benefit from the nice pixmaps in the color group.
  117.  
  118.     if (w->inherits("QPushButton")){
  119.     w->setBackgroundMode( QWidget::NoBackground );
  120.     return;
  121.     }
  122.  
  123.     if ( !w->isTopLevel() ) {
  124.     if ( w->backgroundPixmap() )
  125.         w->setBackgroundOrigin( QWidget::WindowOrigin );
  126.     }
  127. }
  128.  
  129. void MetalStyle::unPolish( QWidget* w)
  130. {
  131.  
  132.    // the polish function sets some widgets to transparent mode and
  133.     // some to translate background mode in order to get the full
  134.     // benefit from the nice pixmaps in the color group.
  135.  
  136.     if (w->inherits("QPushButton")){
  137.     w->setBackgroundMode( QWidget::PaletteButton );
  138.     return;
  139.     }
  140.     if ( !w->isTopLevel() ) {
  141.     if ( w->backgroundPixmap() )
  142.         w->setBackgroundOrigin( QWidget::WidgetOrigin );
  143.     }
  144.  
  145. }
  146.  
  147. void MetalStyle::drawPrimitive( PrimitiveElement pe,
  148.                 QPainter *p,
  149.                 const QRect &r,
  150.                 const QColorGroup &cg,
  151.                 SFlags flags, const QStyleOption& opt ) const
  152. {
  153.     switch( pe ) {
  154.     case PE_HeaderSection:
  155.     if ( flags & Style_Sunken )
  156.         flags ^= Style_Sunken | Style_Raised;
  157.     // fall through
  158.     case PE_ButtonBevel:
  159.     case PE_ButtonCommand:
  160.         drawMetalButton( p, r.x(), r.y(), r.width(), r.height(),
  161.                  (flags & (Style_Sunken|Style_On|Style_Down)),
  162.                  TRUE, !(flags & Style_Raised) );
  163.         break;
  164.     case PE_PanelMenuBar:
  165.     drawMetalFrame( p, r.x(), r.y(), r.width(), r.height() );
  166.     break;
  167.     case PE_ScrollBarAddLine:    
  168.     drawMetalButton( p, r.x(), r.y(), r.width(), r.height(),
  169.              flags & Style_Down, !( flags & Style_Horizontal ) );
  170.     drawPrimitive( (flags & Style_Horizontal) ? PE_ArrowRight :PE_ArrowDown,
  171.                p, r, cg, flags, opt );
  172.     break;
  173.     case PE_ScrollBarSubLine:
  174.     drawMetalButton( p, r.x(), r.y(), r.width(), r.height(),
  175.              flags & Style_Down, !( flags & Style_Horizontal ) );
  176.     drawPrimitive( (flags & Style_Horizontal) ? PE_ArrowLeft : PE_ArrowUp,
  177.                p, r, cg, flags, opt );
  178.     break;
  179.  
  180.     
  181.     case PE_ScrollBarSlider:
  182.     drawMetalButton( p, r.x(), r.y(), r.width(), r.height(), FALSE,
  183.              flags & Style_Horizontal );
  184.     break;
  185.     default:
  186.     QWindowsStyle::drawPrimitive( pe, p, r, cg, flags, opt );
  187.     break;
  188.     }
  189. }
  190.  
  191. void MetalStyle::drawControl( ControlElement element,
  192.                   QPainter *p,
  193.                   const QWidget *widget,
  194.                   const QRect &r,
  195.                   const QColorGroup &cg,
  196.                   SFlags how,
  197.                   const QStyleOption& opt ) const
  198. {
  199.     switch( element ) {
  200.     case CE_PushButton:
  201.     {
  202.         const QPushButton *btn;
  203.         btn = (const QPushButton*)widget;
  204.         int x1, y1, x2, y2;
  205.     
  206.         r.coords( &x1, &y1, &x2, &y2 );
  207.     
  208.         p->setPen( cg.foreground() );
  209.         p->setBrush( QBrush(cg.button(), NoBrush) );
  210.  
  211.     
  212.         QBrush fill;
  213.         if ( btn->isDown() )
  214.         fill = cg.brush( QColorGroup::Mid );
  215.         else if ( btn->isOn() )
  216.         fill = QBrush( cg.mid(), Dense4Pattern );
  217.         else
  218.         fill = cg.brush( QColorGroup::Button );
  219.     
  220.         if ( btn->isDefault() ) {
  221.         QPointArray a;
  222.         a.setPoints( 9,
  223.                  x1, y1, x2, y1, x2, y2, x1, y2, x1, y1+1,
  224.                  x2-1, y1+1, x2-1, y2-1, x1+1, y2-1, x1+1, y1+1 );
  225.         p->setPen( Qt::black );
  226.         p->drawPolyline( a );
  227.         x1 += 2;
  228.         y1 += 2;
  229.         x2 -= 2;
  230.         y2 -= 2;
  231.         }
  232.         SFlags flags = Style_Default;
  233.         if ( btn->isOn() )
  234.         flags |= Style_On;
  235.         if ( btn->isDown() )
  236.         flags |= Style_Down;
  237.         if ( !btn->isFlat() && !btn->isDown() )
  238.         flags |= Style_Raised;
  239.         drawPrimitive( PE_ButtonCommand, p,
  240.                QRect( x1, y1, x2 - x1 + 1, y2 - y1 + 1),
  241.                cg, flags, opt );
  242.     
  243.         if ( btn->isMenuButton() ) {
  244.         flags = Style_Default;
  245.         if ( btn->isEnabled() )
  246.             flags |= Style_Enabled;
  247.         
  248.         int dx = ( y1 - y2 - 4 ) / 3;
  249.         drawPrimitive( PE_ArrowDown, p,
  250.                    QRect(x2 - dx, dx, y1, y2 - y1),
  251.                    cg, flags, opt );
  252.         }
  253.         if ( p->brush().style() != NoBrush )
  254.         p->setBrush( NoBrush );
  255.         break;
  256.     }
  257.     case CE_PushButtonLabel:
  258.     {
  259.         const QPushButton *btn;
  260.         btn = (const QPushButton*)widget;
  261.         int x, y, w, h;
  262.         r.rect( &x, &y, &w, &h );
  263.     
  264.         int x1, y1, x2, y2;
  265.         r.coords( &x1, &y1, &x2, &y2 );
  266.         int dx = 0;
  267.         int dy = 0;
  268.         if ( btn->isMenuButton() )
  269.         dx = ( y2 - y1 ) / 3;
  270.         if ( btn->isOn() || btn->isDown() ) {
  271.         dx--;
  272.         dy--;
  273.         }
  274.         if ( dx || dy )
  275.         p->translate( dx, dy );
  276.         x += 2;
  277.         y += 2;
  278.         w -= 4;
  279.         h -= 4;
  280.         drawItem( p, QRect( x, y, w, h ),
  281.               AlignCenter|ShowPrefix,
  282.               cg, btn->isEnabled(),
  283.               btn->pixmap(), btn->text(), -1,
  284.               (btn->isDown() || btn->isOn())? &cg.brightText() : &cg.buttonText() );
  285.         if ( dx || dy )
  286.         p->translate( -dx, -dy );
  287.         break;
  288.     }
  289.     default:
  290.     QWindowsStyle::drawControl( element, p, widget, r, cg, how, opt );
  291.     break;
  292.     }
  293. }
  294. void MetalStyle::drawComplexControl( ComplexControl cc,
  295.                      QPainter *p,
  296.                      const QWidget *widget,
  297.                      const QRect &r,
  298.                      const QColorGroup &cg,
  299.                      SFlags how,
  300.                      SCFlags sub,
  301.                      SCFlags subActive,
  302.                      const QStyleOption& opt ) const
  303. {
  304.     switch ( cc ) {
  305.     case CC_Slider:
  306.     {
  307.         const QSlider *slider = ( const QSlider* ) widget;
  308.         QRect handle = querySubControlMetrics( CC_Slider, widget,
  309.                            SC_SliderHandle, opt);
  310.         if ( sub & SC_SliderGroove )
  311.         QWindowsStyle::drawComplexControl( cc, p, widget, r, cg, how,
  312.                            SC_SliderGroove, subActive, opt );
  313.         if ( (sub & SC_SliderHandle) && handle.isValid() )
  314.         drawMetalButton( p, handle.x(), handle.y(), handle.width(),
  315.                  handle.height(), FALSE,
  316.                  slider->orientation() == QSlider::Horizontal);
  317.         break;
  318.     }
  319.     case CC_ComboBox:
  320.     {
  321.         // not exactly correct...
  322.         const QComboBox *cmb = ( const QComboBox* ) widget;
  323.     
  324.         qDrawWinPanel( p, r.x(), r.y(), r.width(), r.height(), cg, TRUE,
  325.                cmb->isEnabled() ? &cg.brush( QColorGroup::Base ) :
  326.                                   &cg.brush( QColorGroup::Background ) );
  327.         drawMetalButton( p, r.x() + r.width() - 2 - 16, r.y() + 2, 16, r.height() - 4,
  328.                  how & Style_Sunken, TRUE );
  329.         drawPrimitive( PE_ArrowDown, p,
  330.                QRect( r.x() + r.width() - 2 - 16 + 2,
  331.                   r.y() + 2 + 2, 16 - 4, r.height() - 4 -4 ),
  332.                cg,
  333.                cmb->isEnabled() ? Style_Enabled : Style_Default,
  334.                opt );
  335.         break;
  336.     }
  337.     default:
  338.     QWindowsStyle::drawComplexControl( cc, p, widget, r, cg, how, sub, subActive,
  339.                        opt );
  340.     break;
  341.     }
  342. }
  343.         
  344.  
  345. /*!
  346.   Draw a metallic button, sunken if \a sunken is TRUE, horizontal if
  347.   /a horz is TRUE.
  348. */
  349.  
  350. void MetalStyle::drawMetalButton( QPainter *p, int x, int y, int w, int h,
  351.                   bool sunken, bool horz, bool flat  ) const
  352. {
  353.  
  354.     drawMetalFrame( p, x, y, w, h );
  355.     drawMetalGradient( p, x, y, w, h, sunken, horz, flat );
  356. }
  357.  
  358.  
  359.  
  360.  
  361. void MetalStyle::drawMetalFrame( QPainter *p, int x, int y, int w, int h ) const
  362. {
  363.     QColor top1("#878769691515");
  364.     QColor top2("#C6C6B4B44949");
  365.  
  366.     QColor bot2("#70705B5B1414");
  367.     QColor bot1("#56564A4A0E0E"); //first from the bottom
  368.  
  369.  
  370.     int x2 = x + w - 1;
  371.     int y2 = y + h - 1;
  372.  
  373.     //frame:
  374.  
  375.     p->setPen( top1 );
  376.     p->drawLine( x, y2, x, y );
  377.     p->drawLine( x, y, x2-1, y );
  378.     p->setPen( top2 );
  379.     p->drawLine( x+1, y2 -1, x+1, y+1 );
  380.     p->drawLine( x+1, y+1 , x2-2, y+1 );
  381.  
  382.     p->setPen( bot1 );
  383.     p->drawLine( x+1, y2, x2, y2 );
  384.     p->drawLine( x2, y2, x2, y );
  385.     p->setPen( bot2 );
  386.     p->drawLine( x+1, y2-1, x2-1, y2-1 );
  387.     p->drawLine( x2-1, y2-1, x2-1, y+1 );
  388.  
  389.  
  390. }
  391.  
  392.  
  393. void MetalStyle::drawMetalGradient( QPainter *p, int x, int y, int w, int h,
  394.                     bool sunken, bool horz, bool flat  ) const
  395.  
  396. {
  397.     QColor highlight("#E8E8DDDD6565");
  398.     QColor subh1("#CECEBDBD5151");
  399.     QColor subh2("#BFBFACAC4545");
  400.  
  401.     QColor topgrad("#B9B9A5A54040");
  402.     QColor botgrad("#89896C6C1A1A");
  403.  
  404.  
  405.  
  406.     if ( flat && !sunken ) {
  407.         p->fillRect( x + 2, y + 2, w - 4,h -4, topgrad );
  408.     } else {
  409.     // highlight:
  410.     int i = 0;
  411.     int x1 = x + 2;
  412.     int y1 = y + 2;
  413.     int x2 = x + w - 1;
  414.     int y2 = y + h - 1;
  415.     if ( horz )
  416.         x2 = x2 - 2;
  417.     else
  418.         y2 = y2 - 2;
  419.     
  420. #define DRAWLINE if (horz) \
  421.                     p->drawLine( x1, y1+i, x2, y1+i ); \
  422.          else \
  423.                     p->drawLine( x1+i, y1, x1+i, y2 ); \
  424.                  i++;
  425.  
  426.     if ( !sunken ) {
  427.         p->setPen( highlight );
  428.         DRAWLINE;
  429.         DRAWLINE;
  430.         p->setPen( subh1 );
  431.         DRAWLINE;
  432.         p->setPen( subh2 );
  433.         DRAWLINE;
  434.     }
  435.     // gradient:
  436.     int ng = (horz ? h : w) - 8; // how many lines for the gradient?
  437.     
  438.     int h1, h2, s1, s2, v1, v2;
  439.     if ( !sunken ) {
  440.         topgrad.hsv( &h1, &s1, &v1 );
  441.         botgrad.hsv( &h2, &s2, &v2 );
  442.     } else {
  443.         botgrad.hsv( &h1, &s1, &v1 );
  444.         topgrad.hsv( &h2, &s2, &v2 );
  445.     }
  446.     
  447.     if ( ng > 1 ) {    
  448.         for ( int j =0; j < ng; j++ ) {
  449.         p->setPen( QColor( h1 + ((h2-h1)*j)/(ng-1),
  450.                    s1 + ((s2-s1)*j)/(ng-1),
  451.                    v1 + ((v2-v1)*j)/(ng-1),  QColor::Hsv ) );
  452.         DRAWLINE;
  453.         }
  454.     } else if ( ng == 1 ) {
  455.         p->setPen( QColor((h1+h2)/2, (s1+s2)/2, (v1+v2)/2, QColor::Hsv) );
  456.         DRAWLINE;
  457.     }
  458.     if ( sunken ) {
  459.         p->setPen( subh2 );
  460.         DRAWLINE;
  461.         
  462.         p->setPen( subh1 );
  463.         DRAWLINE;
  464.         
  465.         p->setPen( highlight );
  466.         DRAWLINE;
  467.         DRAWLINE;
  468.     }
  469.     }    
  470. }
  471.  
  472.  
  473.  
  474. int MetalStyle::pixelMetric( PixelMetric metric, const QWidget *w ) const
  475. {
  476.     switch ( metric ) {
  477.     case PM_MenuBarFrameWidth:
  478.     return 2;
  479.     default:
  480.     return QWindowsStyle::pixelMetric( metric, w );
  481.     }
  482. }
  483.