demos/shared/arthurstyle.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** Copyright (C) 2005-2006 Trolltech ASA. All rights reserved.
00004 **
00005 ** This file is part of the demonstration applications of the Qt Toolkit.
00006 **
00007 ** This file may be used under the terms of the GNU General Public
00008 ** License version 2.0 as published by the Free Software Foundation
00009 ** and appearing in the file LICENSE.GPL included in the packaging of
00010 ** this file.  Please review the following information to ensure GNU
00011 ** General Public Licensing requirements will be met:
00012 ** http://www.trolltech.com/products/qt/opensource.html
00013 **
00014 ** If you are unsure which license is appropriate for your use, please
00015 ** review the following information:
00016 ** http://www.trolltech.com/products/qt/licensing.html or contact the
00017 ** sales department at sales@trolltech.com.
00018 **
00019 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00020 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00021 **
00022 ****************************************************************************/
00023 
00024 #include "arthurstyle.h"
00025 #include "arthurwidgets.h"
00026 #include <QLayout>
00027 #include <QPainter>
00028 #include <QPainterPath>
00029 #include <QPixmapCache>
00030 #include <QRadioButton>
00031 #include <QString>
00032 #include <QStyleOption>
00033 #include <QtDebug>
00034 
00035 QPixmap cached(const QString &img)
00036 {
00037     if (QPixmap *p = QPixmapCache::find(img))
00038         return *p;
00039 
00040     QPixmap pm;
00041     pm = QPixmap::fromImage(QImage(img), Qt::OrderedDither | Qt::OrderedAlphaDither);
00042     if (pm.isNull())
00043         return QPixmap();
00044 
00045     QPixmapCache::insert(img, pm);
00046     return pm;
00047 }
00048 
00049 
00050 ArthurStyle::ArthurStyle()
00051     : QWindowsStyle()
00052 {
00053     Q_INIT_RESOURCE(shared);
00054 }
00055 
00056 
00057 void ArthurStyle::drawHoverRect(QPainter *painter, const QRect &r) const
00058 {
00059     double h = r.height();
00060     double h2 = r.height() / 2.0;
00061     QPainterPath path;
00062     path.addRect(r.x() + h2, r.y() + 0, r.width() - h2 * 2, r.height());
00063     path.addEllipse(r.x(), r.y(), h, h);
00064     path.addEllipse(r.x() + r.width() - h, r.y(), h, h);
00065     path.setFillRule(Qt::WindingFill);
00066     painter->setPen(Qt::NoPen);
00067     painter->setBrush(QColor(191, 215, 191));
00068     painter->setRenderHint(QPainter::Antialiasing);
00069     painter->drawPath(path);
00070 }
00071 
00072 
00073 void ArthurStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option,
00074                                 QPainter *painter, const QWidget *widget) const
00075 {
00076 
00077     Q_ASSERT(option);
00078     switch (element) {
00079     case PE_FrameFocusRect:
00080         break;
00081 
00082     case PE_IndicatorRadioButton:
00083         if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
00084             bool hover = (button->state & State_Enabled) && (button->state & State_MouseOver);
00085             painter->save();
00086             QPixmap radio;
00087             if (hover)
00088                 drawHoverRect(painter, widget->rect());
00089 
00090             if (button->state & State_Sunken)
00091                 radio = cached(":res/images/radiobutton-on.png");
00092             else if (button->state & State_On)
00093                 radio = cached(":res/images/radiobutton_on.png");
00094             else
00095                 radio = cached(":res/images/radiobutton_off.png");
00096             painter->drawPixmap(button->rect.topLeft(), radio);
00097 
00098             painter->restore();
00099         }
00100         break;
00101 
00102     case PE_PanelButtonCommand:
00103         if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
00104             bool hover = (button->state & State_Enabled) && (button->state & State_MouseOver);
00105 
00106             painter->save();
00107             const QPushButton *pushButton = qobject_cast<const QPushButton *>(widget);
00108             Q_ASSERT(pushButton);
00109             QWidget *parent = pushButton->parentWidget();
00110             if (parent && qobject_cast<QGroupBox *>(parent)) {
00111                 QLinearGradient lg(0, 0, 0, parent->height());
00112                 lg.setColorAt(0, QColor(224,224,224));
00113                 lg.setColorAt(1, QColor(255,255,255));
00114                 painter->setPen(Qt::NoPen);
00115                 painter->setBrush(lg);
00116                 painter->setBrushOrigin(-widget->mapToParent(QPoint(0,0)));
00117                 painter->drawRect(button->rect);
00118                 painter->setBrushOrigin(0,0);
00119             }
00120 
00121             bool down = (button->state & State_Sunken) || (button->state & State_On);
00122 
00123             QPixmap left, right, mid;
00124             if (down) {
00125                 left = cached(":res/images/button_pressed_cap_left.png");
00126                 right = cached(":res/images/button_pressed_cap_right.png");
00127                 mid = cached(":res/images/button_pressed_stretch.png");
00128             } else {
00129                 left = cached(":res/images/button_normal_cap_left.png");
00130                 right = cached(":res/images/button_normal_cap_right.png");
00131                 mid = cached(":res/images/button_normal_stretch.png");
00132             }
00133             painter->drawPixmap(button->rect.topLeft(), left);
00134             painter->drawTiledPixmap(QRect(button->rect.x() + left.width(),
00135                                            button->rect.y(),
00136                                            button->rect.width() - left.width() - right.width(),
00137                                            left.height()),
00138                                      mid);
00139             painter->drawPixmap(button->rect.x() + button->rect.width() - right.width(),
00140                                 button->rect.y(),
00141                                 right);
00142             if (hover)
00143                 painter->fillRect(widget->rect().adjusted(3,5,-3,-5), QColor(31,127,31,63));
00144             painter->restore();
00145         }
00146         break;
00147 
00148     case PE_FrameGroupBox:
00149         if (const QStyleOptionFrameV2 *group
00150                 = qstyleoption_cast<const QStyleOptionFrameV2 *>(option)) {
00151             const QRect &r = group->rect;
00152 
00153             painter->save();
00154             int radius = 14;
00155             int radius2 = radius*2;
00156             QPainterPath clipPath;
00157             clipPath.moveTo(radius, 0);
00158             clipPath.arcTo(r.right() - radius2, 0, radius2, radius2, 90, -90);
00159             clipPath.arcTo(r.right() - radius2, r.bottom() - radius2, radius2, radius2, 0, -90);
00160             clipPath.arcTo(r.left(), r.bottom() - radius2, radius2, radius2, 270, -90);
00161             clipPath.arcTo(r.left(), r.top(), radius2, radius2, 180, -90);
00162             painter->setClipPath(clipPath);
00163             QPixmap titleStretch = cached(":res/images/title_stretch.png");
00164             QPixmap topLeft = cached(":res/images/groupframe_topleft.png");
00165             QPixmap topRight = cached(":res/images/groupframe_topright.png");
00166             QPixmap bottomLeft = cached(":res/images/groupframe_bottom_left.png");
00167             QPixmap bottomRight = cached(":res/images/groupframe_bottom_right.png");
00168             QPixmap leftStretch = cached(":res/images/groupframe_left_stretch.png");
00169             QPixmap topStretch = cached(":res/images/groupframe_top_stretch.png");
00170             QPixmap rightStretch = cached(":res/images/groupframe_right_stretch.png");
00171             QPixmap bottomStretch = cached(":res/images/groupframe_bottom_stretch.png");
00172             QLinearGradient lg(0, 0, 0, r.height());
00173             lg.setColorAt(0, QColor(224,224,224));
00174             lg.setColorAt(1, QColor(255,255,255));
00175             painter->setPen(Qt::NoPen);
00176             painter->setBrush(lg);
00177             painter->drawRect(r.adjusted(0, titleStretch.height()/2, 0, 0));
00178             painter->setClipping(false);
00179 
00180             int topFrameOffset = titleStretch.height()/2 - 2;
00181             painter->drawPixmap(r.topLeft() + QPoint(0, topFrameOffset), topLeft);
00182             painter->drawPixmap(r.topRight() - QPoint(topRight.width()-1, 0)
00183                                 + QPoint(0, topFrameOffset), topRight);
00184             painter->drawPixmap(r.bottomLeft() - QPoint(0, bottomLeft.height()-1), bottomLeft);
00185             painter->drawPixmap(r.bottomRight() - QPoint(bottomRight.width()-1,
00186                                 bottomRight.height()-1), bottomRight);
00187 
00188             QRect left = r;
00189             left.setY(r.y() + topLeft.height() + topFrameOffset);
00190             left.setWidth(leftStretch.width());
00191             left.setHeight(r.height() - topLeft.height() - bottomLeft.height() - topFrameOffset);
00192             painter->drawTiledPixmap(left, leftStretch);
00193 
00194             QRect top = r;
00195             top.setX(r.x() + topLeft.width());
00196             top.setY(r.y() + topFrameOffset);
00197             top.setWidth(r.width() - topLeft.width() - topRight.width());
00198             top.setHeight(topLeft.height());
00199             painter->drawTiledPixmap(top, topStretch);
00200 
00201             QRect right = r;
00202             right.setX(r.right() - rightStretch.width()+1);
00203             right.setY(r.y() + topRight.height() + topFrameOffset);
00204             right.setWidth(rightStretch.width());
00205             right.setHeight(r.height() - topRight.height()
00206                             - bottomRight.height() - topFrameOffset);
00207             painter->drawTiledPixmap(right, rightStretch);
00208 
00209             QRect bottom = r;
00210             bottom.setX(r.x() + bottomLeft.width());
00211             bottom.setY(r.bottom() - bottomStretch.height()+1);
00212             bottom.setWidth(r.width() - bottomLeft.width() - bottomRight.width());
00213             bottom.setHeight(bottomLeft.height());
00214             painter->drawTiledPixmap(bottom, bottomStretch);
00215             painter->restore();
00216         }
00217         break;
00218 
00219     default:
00220         QWindowsStyle::drawPrimitive(element, option, painter, widget);
00221         break;
00222     }
00223     return;
00224 }
00225 
00226 
00227 void ArthurStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
00228                                      QPainter *painter, const QWidget *widget) const
00229 {
00230     switch (control) {
00231     case CC_Slider:
00232         if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
00233             QRect groove = subControlRect(CC_Slider, option, SC_SliderGroove, widget);
00234             QRect handle = subControlRect(CC_Slider, option, SC_SliderHandle, widget);
00235 
00236             painter->save();
00237 
00238             bool hover = (slider->state & State_Enabled) && (slider->state & State_MouseOver);
00239             if (hover) {
00240                 QRect moderated = widget->rect().adjusted(0, 4, 0, -4);
00241                 drawHoverRect(painter, moderated);
00242             }
00243 
00244             if ((option->subControls & SC_SliderGroove) && groove.isValid()) {
00245                 QPixmap grv = cached(":res/images/slider_bar.png");
00246                 painter->drawPixmap(QRect(groove.x() + 5, groove.y(),
00247                                           groove.width() - 10, grv.height()),
00248                                     grv);
00249             }
00250             if ((option->subControls & SC_SliderHandle) && handle.isValid()) {
00251                 QPixmap hndl = cached(":res/images/slider_thumb_on.png");
00252                 painter->drawPixmap(handle.topLeft(), hndl);
00253             }
00254 
00255             painter->restore();
00256         }
00257         break;
00258     case CC_GroupBox:
00259         if (const QStyleOptionGroupBox *groupBox
00260                 = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
00261             QStyleOptionGroupBox groupBoxCopy(*groupBox);
00262             groupBoxCopy.subControls &= ~SC_GroupBoxLabel;
00263             QWindowsStyle::drawComplexControl(control, &groupBoxCopy, painter, widget);
00264 
00265             if (groupBox->subControls & SC_GroupBoxLabel) {
00266                 const QRect &r = groupBox->rect;
00267                 QPixmap titleLeft = cached(":res/images/title_cap_left.png");
00268                 QPixmap titleRight = cached(":res/images/title_cap_right.png");
00269                 QPixmap titleStretch = cached(":res/images/title_stretch.png");
00270                 int txt_width = groupBox->fontMetrics.width(groupBox->text) + 20;
00271                 painter->drawPixmap(r.center().x() - txt_width/2, 0, titleLeft);
00272                 QRect tileRect = subControlRect(control, groupBox, SC_GroupBoxLabel, widget);
00273                 painter->drawTiledPixmap(tileRect, titleStretch);
00274                 painter->drawPixmap(tileRect.x() + tileRect.width(), 0, titleRight);
00275                 int opacity = 31;
00276                 painter->setPen(QColor(0, 0, 0, opacity));
00277                 painter->drawText(tileRect.translated(0, 1),
00278                                   Qt::AlignVCenter | Qt::AlignHCenter, groupBox->text);
00279                 painter->drawText(tileRect.translated(2, 1),
00280                                   Qt::AlignVCenter | Qt::AlignHCenter, groupBox->text);
00281                 painter->setPen(QColor(0, 0, 0, opacity * 2));
00282                 painter->drawText(tileRect.translated(1, 1),
00283                                   Qt::AlignVCenter | Qt::AlignHCenter, groupBox->text);
00284                 painter->setPen(Qt::white);
00285                 painter->drawText(tileRect, Qt::AlignVCenter | Qt::AlignHCenter, groupBox->text);
00286             }
00287         }
00288         break;
00289     default:
00290         QWindowsStyle::drawComplexControl(control, option, painter, widget);
00291         break;
00292     }
00293     return;
00294 }
00295 
00296 QRect ArthurStyle::subControlRect(ComplexControl control, const QStyleOptionComplex *option,
00297                                   SubControl subControl, const QWidget *widget) const
00298 {
00299     QRect rect;
00300 
00301     switch (control) {
00302     default:
00303         rect = QWindowsStyle::subControlRect(control, option, subControl, widget);
00304         break;
00305     case CC_GroupBox:
00306         if (const QStyleOptionGroupBox *group
00307                 = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
00308             switch (subControl) {
00309             default:
00310                 rect = QWindowsStyle::subControlRect(control, option, subControl, widget);
00311                 break;
00312             case SC_GroupBoxContents:
00313                 rect = QWindowsStyle::subControlRect(control, option, subControl, widget);
00314                 rect.adjust(0, -8, 0, 0);
00315                 break;
00316             case SC_GroupBoxFrame:
00317                 rect = group->rect;
00318                 break;
00319             case SC_GroupBoxLabel:
00320                 QPixmap titleLeft = cached(":res/images/title_cap_left.png");
00321                 QPixmap titleRight = cached(":res/images/title_cap_right.png");
00322                 QPixmap titleStretch = cached(":res/images/title_stretch.png");
00323                 int txt_width = group->fontMetrics.width(group->text) + 20;
00324                 rect = QRect(group->rect.center().x() - txt_width/2 + titleLeft.width(), 0,
00325                              txt_width - titleLeft.width() - titleRight.width(),
00326                              titleStretch.height());
00327                 break;
00328             }
00329         }
00330         break;
00331     }
00332 
00333     if (control == CC_Slider && subControl == SC_SliderHandle) {
00334         rect.setWidth(13);
00335         rect.setHeight(27);
00336     } else if (control == CC_Slider && subControl == SC_SliderGroove) {
00337         rect.setHeight(9);
00338         rect.moveTop(27/2 - 9/2);
00339     }
00340     return rect;
00341 }
00342 
00343 QSize ArthurStyle::sizeFromContents(ContentsType type, const QStyleOption *option,
00344                                     const QSize &size, const QWidget *widget) const
00345 {
00346     QSize newSize = QWindowsStyle::sizeFromContents(type, option, size, widget);
00347 
00348 
00349     switch (type) {
00350     case CT_RadioButton:
00351         newSize += QSize(20, 0);
00352         break;
00353 
00354     case CT_PushButton:
00355         newSize.setHeight(26);
00356         break;
00357 
00358     case CT_Slider:
00359         newSize.setHeight(27);
00360         break;
00361 
00362     default:
00363         break;
00364     }
00365 
00366     return newSize;
00367 }
00368 
00369 int ArthurStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QWidget *widget) const
00370 {
00371     if (pm == PM_SliderLength)
00372         return 13;
00373     return QWindowsStyle::pixelMetric(pm, opt, widget);
00374 }
00375 
00376 void ArthurStyle::polish(QWidget *widget)
00377 {
00378     if (widget->layout() && qobject_cast<QGroupBox *>(widget)) {
00379         if (qFindChildren<QGroupBox *>(widget).size() == 0)
00380             widget->layout()->setSpacing(0);
00381         else
00382             widget->layout()->setMargin(10);
00383     }
00384 
00385     if (qobject_cast<QPushButton *>(widget)
00386         || qobject_cast<QRadioButton *>(widget)
00387         || qobject_cast<QSlider *>(widget)) {
00388         widget->setAttribute(Qt::WA_Hover);
00389     }
00390 
00391     QPalette pal = widget->palette();
00392     if (widget->isWindow()) {
00393         pal.setColor(QPalette::Background, QColor(241, 241, 241));
00394         widget->setPalette(pal);
00395     }
00396 
00397 }
00398 
00399 void ArthurStyle::unpolish(QWidget *widget)
00400 {
00401     if (qobject_cast<QPushButton *>(widget)
00402         || qobject_cast<QRadioButton *>(widget)
00403         || qobject_cast<QSlider *>(widget)) {
00404         widget->setAttribute(Qt::WA_Hover, false);
00405     }
00406 }
00407 
00408 void ArthurStyle::polish(QPalette &palette)
00409 {
00410     palette.setColor(QPalette::Background, QColor(241, 241, 241));
00411 }
00412 
00413 QRect ArthurStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const
00414 {
00415     QRect r;
00416     switch(element) {
00417     case SE_RadioButtonClickRect:
00418         r = widget->rect();
00419         break;
00420     case SE_RadioButtonContents:
00421         r = widget->rect().adjusted(20, 0, 0, 0);
00422         break;
00423     default:
00424         r = QWindowsStyle::subElementRect(element, option, widget);
00425         break;
00426     }
00427 
00428     if (qobject_cast<const QRadioButton*>(widget))
00429         r = r.adjusted(5, 0, -5, 0);
00430 
00431     return r;
00432 }

Generated on Thu Mar 15 11:52:35 2007 for Qt 4.2 User's Guide by  doxygen 1.5.1