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