/************************************************************************** ** ** This file is part of Qt Creator ** ** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** Commercial Usage ** ** Licensees holding valid Qt Commercial licenses may use this file in ** accordance with the Qt Commercial License Agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and Nokia. ** ** GNU Lesser General Public License Usage ** ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** If you are unsure which license is appropriate for your use, please ** contact the sales department at http://qt.nokia.com/contact. ** **************************************************************************/ #include "manhattanstyle.h" #include "styleanimator.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // We define a currently unused state for indicating animations #define State_Animating 0x00000040 // Because designer needs to disable this for widget previews // we have a custom property that is inherited bool styleEnabled(const QWidget *widget) { const QWidget *p = widget; while (p) { if (p->property("_q_custom_style_disabled").toBool()) return false; p = p->parentWidget(); } return true; } // Consider making this a QStyle state bool panelWidget(const QWidget *widget) { const QWidget *p = widget; while (p) { if (qobject_cast(p) && styleEnabled(p)) return true; else if (qobject_cast(p) && styleEnabled(p)) return true; else if (qobject_cast(p) && styleEnabled(p)) return true; else if (p->property("panelwidget").toBool()) return true; p = p->parentWidget(); } return false; } class ManhattanStylePrivate { public: ManhattanStylePrivate(const QString &baseStyleName) { style = QStyleFactory::create(baseStyleName); QTC_ASSERT(style, /**/); lineeditImage = QImage(":/core/images/inputfield.png"); lineeditImage_disabled = QImage(":/core/images/inputfield_disabled.png"); } ~ManhattanStylePrivate() { delete style; style = 0; } void init(); public: QStyle *style; QImage lineeditImage; QImage lineeditImage_disabled; StyleAnimator animator; }; ManhattanStyle::ManhattanStyle(const QString &baseStyleName) : QWindowsStyle(), d(new ManhattanStylePrivate(baseStyleName)) { } ManhattanStyle::~ManhattanStyle() { delete d; d = 0; } QStyle *ManhattanStyle::systemStyle() const { return d->style; } // Draws a CSS-like border image where the defined borders are not stretched void drawCornerImage(const QImage &img, QPainter *painter, QRect rect, int left = 0, int top = 0, int right = 0, int bottom = 0) { QSize size = img.size(); if (top > 0) { //top painter->drawImage(QRect(rect.left() + left, rect.top(), rect.width() -right - left, top), img, QRect(left, 0, size.width() -right - left, top)); if (left > 0) //top-left painter->drawImage(QRect(rect.left(), rect.top(), left, top), img, QRect(0, 0, left, top)); if (right > 0) //top-right painter->drawImage(QRect(rect.left() + rect.width() - right, rect.top(), right, top), img, QRect(size.width() - right, 0, right, top)); } //left if (left > 0) painter->drawImage(QRect(rect.left(), rect.top()+top, left, rect.height() - top - bottom), img, QRect(0, top, left, size.height() - bottom - top)); //center painter->drawImage(QRect(rect.left() + left, rect.top()+top, rect.width() -right - left, rect.height() - bottom - top), img, QRect(left, top, size.width() -right -left, size.height() - bottom - top)); if (right > 0) //right painter->drawImage(QRect(rect.left() +rect.width() - right, rect.top()+top, right, rect.height() - top - bottom), img, QRect(size.width() - right, top, right, size.height() - bottom - top)); if (bottom > 0) { //bottom painter->drawImage(QRect(rect.left() +left, rect.top() + rect.height() - bottom, rect.width() - right - left, bottom), img, QRect(left, size.height() - bottom, size.width() - right - left, bottom)); if (left > 0) //bottom-left painter->drawImage(QRect(rect.left(), rect.top() + rect.height() - bottom, left, bottom), img, QRect(0, size.height() - bottom, left, bottom)); if (right > 0) //bottom-right painter->drawImage(QRect(rect.left() + rect.width() - right, rect.top() + rect.height() - bottom, right, bottom), img, QRect(size.width() - right, size.height() - bottom, right, bottom)); } } QPixmap ManhattanStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const { QPixmap result; result = d->style->generatedIconPixmap(iconMode, pixmap, opt); return result; } int ManhattanStyle::layoutSpacingImplementation(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2, Qt::Orientation orientation, const QStyleOption * option , const QWidget * widget ) const { return d->style->layoutSpacing(control1, control2, orientation, option, widget); } QSize ManhattanStyle::sizeFromContents(ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget) const { QSize newSize = d->style->sizeFromContents(type, option, size, widget); if (type == CT_Splitter && widget && widget->property("minisplitter").toBool()) return QSize(1, 1); else if (type == CT_ComboBox && panelWidget(widget)) newSize += QSize(14, 0); return newSize; } QRect ManhattanStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const { QRect rect; rect = d->style->subElementRect(element, option, widget); return rect; } QRect ManhattanStyle::subControlRect(ComplexControl control, const QStyleOptionComplex *option, SubControl subControl, const QWidget *widget) const { QRect rect; rect = d->style->subControlRect(control, option, subControl, widget); return rect; } QStyle::SubControl ManhattanStyle::hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option, const QPoint &pos, const QWidget *widget) const { SubControl result = QStyle::SC_None; result = d->style->hitTestComplexControl(control, option, pos, widget); return result; } int ManhattanStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const { int retval = 0; retval = d->style->pixelMetric(metric, option, widget); switch (metric) { case PM_SplitterWidth: if (widget && widget->property("minisplitter").toBool()) retval = 1; break; case PM_ToolBarIconSize: if (panelWidget(widget)) retval = 16; break; case PM_MenuPanelWidth: case PM_MenuBarHMargin: case PM_MenuBarVMargin: case PM_ToolBarFrameWidth: if (panelWidget(widget)) retval = 1; break; case PM_ButtonShiftVertical: case PM_ButtonShiftHorizontal: case PM_MenuBarPanelWidth: case PM_ToolBarItemMargin: case PM_ToolBarItemSpacing: if (panelWidget(widget)) retval = 0; break; case PM_DefaultFrameWidth: if (qobject_cast(widget) && panelWidget(widget)) return 1; break; default: break; } return retval; } QPalette ManhattanStyle::standardPalette() const { QPalette result; result = d->style->standardPalette(); return result; } void ManhattanStyle::polish(QApplication *app) { d->style->polish(app); } void ManhattanStyle::unpolish(QApplication *app) { d->style->unpolish(app); } QPalette panelPalette(const QPalette &oldPalette) { QColor color = Utils::StyleHelper::panelTextColor(); QPalette pal = oldPalette; pal.setBrush(QPalette::All, QPalette::WindowText, color); pal.setBrush(QPalette::All, QPalette::ButtonText, color); pal.setBrush(QPalette::All, QPalette::Foreground, color); color.setAlpha(100); pal.setBrush(QPalette::Disabled, QPalette::WindowText, color); pal.setBrush(QPalette::Disabled, QPalette::ButtonText, color); pal.setBrush(QPalette::Disabled, QPalette::Foreground, color); return pal; } void ManhattanStyle::polish(QWidget *widget) { d->style->polish(widget); // OxygenStyle forces a rounded widget mask on toolbars if (d->style->inherits("OxygenStyle")) { if (qobject_cast(widget)) widget->removeEventFilter(d->style); } if (panelWidget(widget)) { widget->setAttribute(Qt::WA_LayoutUsesWidgetRect, true); if (qobject_cast(widget)) { widget->setAttribute(Qt::WA_Hover); widget->setMaximumHeight(Utils::StyleHelper::navigationWidgetHeight() - 2); } else if (qobject_cast(widget)) { widget->setAttribute(Qt::WA_Hover); widget->setMaximumHeight(Utils::StyleHelper::navigationWidgetHeight() - 2); } else if (qobject_cast(widget)) widget->setPalette(panelPalette(widget->palette())); else if (qobject_cast(widget) || widget->property("panelwidget_singlerow").toBool()) widget->setFixedHeight(Utils::StyleHelper::navigationWidgetHeight()); else if (qobject_cast(widget)) widget->setFixedHeight(Utils::StyleHelper::navigationWidgetHeight() + 2); else if (qobject_cast(widget)) { widget->setMaximumHeight(Utils::StyleHelper::navigationWidgetHeight() - 2); widget->setAttribute(Qt::WA_Hover); } } } void ManhattanStyle::unpolish(QWidget *widget) { d->style->unpolish(widget); if (panelWidget(widget)) { widget->setAttribute(Qt::WA_LayoutUsesWidgetRect, false); if (qobject_cast(widget)) widget->setAttribute(Qt::WA_Hover, false); else if (qobject_cast(widget)) widget->setAttribute(Qt::WA_Hover, false); else if (qobject_cast(widget)) widget->setAttribute(Qt::WA_Hover, false); } } void ManhattanStyle::polish(QPalette &pal) { d->style->polish(pal); } QIcon ManhattanStyle::standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget) const { QIcon icon; switch (standardIcon) { case QStyle::SP_TitleBarCloseButton: case QStyle::SP_ToolBarHorizontalExtensionButton: return QIcon(standardPixmap(standardIcon, option, widget)); default: icon = d->style->standardIcon(standardIcon, option, widget); } return icon; } QPixmap ManhattanStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, const QWidget *widget) const { if (widget && !panelWidget(widget)) return d->style->standardPixmap(standardPixmap, opt, widget); QPixmap pixmap; switch (standardPixmap) { case QStyle::SP_ToolBarHorizontalExtensionButton: { static const QPixmap extButton(":/core/images/extension.png"); pixmap = extButton; } break; case QStyle::SP_TitleBarCloseButton: { static const QPixmap closeButton(":/core/images/closebutton.png"); pixmap = closeButton; } break; default: pixmap = d->style->standardPixmap(standardPixmap, opt, widget); } return pixmap; } int ManhattanStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget, QStyleHintReturn *returnData) const { int ret = d->style->styleHint(hint, option, widget, returnData); switch (hint) { // Make project explorer alternate rows all the way case QStyle::SH_ItemView_PaintAlternatingRowColorsForEmptyArea: if (widget && widget->property("AlternateEmpty").toBool()) ret = true; break; case QStyle::SH_EtchDisabledText: if (panelWidget(widget)) ret = false; break; default: break; } return ret; } void ManhattanStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const { if (!panelWidget(widget)) return d->style->drawPrimitive(element, option, painter, widget); bool animating = (option->state & State_Animating); int state = option->state; QRect rect = option->rect; QRect oldRect; QRect newRect; if (widget && (element == PE_PanelButtonTool) && !animating) { QWidget *w = const_cast (widget); int oldState = w->property("_q_stylestate").toInt(); oldRect = w->property("_q_stylerect").toRect(); newRect = w->rect(); w->setProperty("_q_stylestate", (int)option->state); w->setProperty("_q_stylerect", w->rect()); // Determine the animated transition bool doTransition = ((state & State_On) != (oldState & State_On) || (state & State_MouseOver) != (oldState & State_MouseOver)); if (oldRect != newRect) { doTransition = false; d->animator.stopAnimation(widget); } if (doTransition) { QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied); QImage endImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied); Animation *anim = d->animator.widgetAnimation(widget); QStyleOption opt = *option; opt.state = (QStyle::State)oldState; opt.state |= (State)State_Animating; startImage.fill(0); Transition *t = new Transition; t->setWidget(w); QPainter startPainter(&startImage); if (!anim) { drawPrimitive(element, &opt, &startPainter, widget); } else { anim->paint(&startPainter, &opt); d->animator.stopAnimation(widget); } QStyleOption endOpt = *option; endOpt.state |= (State)State_Animating; t->setStartImage(startImage); d->animator.startAnimation(t); endImage.fill(0); QPainter endPainter(&endImage); drawPrimitive(element, &endOpt, &endPainter, widget); t->setEndImage(endImage); if (oldState & State_MouseOver) t->setDuration(150); else t->setDuration(75); t->setStartTime(QTime::currentTime()); } } switch (element) { case PE_PanelLineEdit: { painter->save(); // Fill the line edit background QRect filledRect = option->rect.adjusted(1, 1, -1, -1); painter->setBrushOrigin(filledRect.topLeft()); painter->fillRect(filledRect, option->palette.base()); if (option->state & State_Enabled) drawCornerImage(d->lineeditImage, painter, option->rect, 2, 2, 2, 2); else drawCornerImage(d->lineeditImage_disabled, painter, option->rect, 2, 2, 2, 2); if (option->state & State_HasFocus || option->state & State_MouseOver) { QColor hover = Utils::StyleHelper::baseColor(); if (state & State_HasFocus) hover.setAlpha(100); else hover.setAlpha(50); painter->setPen(QPen(hover, 1)); painter->drawRect(option->rect.adjusted(1, 1, -2 ,-2)); } painter->restore(); } break; case PE_FrameStatusBarItem: break; case PE_PanelButtonTool: { Animation *anim = d->animator.widgetAnimation(widget); if (!animating && anim) { anim->paint(painter, option); } else { bool pressed = option->state & State_Sunken || option->state & State_On; QColor shadow(0, 0, 0, 30); painter->setPen(shadow); if (pressed) { QColor shade(0, 0, 0, 40); painter->fillRect(rect, shade); painter->drawLine(rect.topLeft() + QPoint(1, 0), rect.topRight() - QPoint(1, 0)); painter->drawLine(rect.topLeft(), rect.bottomLeft()); painter->drawLine(rect.topRight(), rect.bottomRight()); // painter->drawLine(rect.bottomLeft() + QPoint(1, 0), rect.bottomRight() - QPoint(1, 0)); QColor highlight(255, 255, 255, 30); painter->setPen(highlight); } else if (option->state & State_Enabled && option->state & State_MouseOver) { QColor lighter(255, 255, 255, 37); painter->fillRect(rect, lighter); } } } break; case PE_PanelStatusBar: { painter->save(); QLinearGradient grad(option->rect.topLeft(), QPoint(rect.center().x(), rect.bottom())); QColor startColor = Utils::StyleHelper::shadowColor().darker(164); QColor endColor = Utils::StyleHelper::baseColor().darker(130); grad.setColorAt(0, startColor); grad.setColorAt(1, endColor); painter->fillRect(option->rect, grad); painter->setPen(QColor(255, 255, 255, 60)); painter->drawLine(rect.topLeft() + QPoint(0,1), rect.topRight()+ QPoint(0,1)); painter->setPen(Utils::StyleHelper::borderColor().darker(110)); painter->drawLine(rect.topLeft(), rect.topRight()); painter->restore(); } break; case PE_IndicatorToolBarSeparator: { QColor separatorColor = Utils::StyleHelper::borderColor(); separatorColor.setAlpha(100); painter->setPen(separatorColor); const int margin = 6; if (option->state & State_Horizontal) { const int offset = rect.width()/2; painter->drawLine(rect.bottomLeft().x() + offset, rect.bottomLeft().y() - margin, rect.topLeft().x() + offset, rect.topLeft().y() + margin); } else { //Draw vertical separator const int offset = rect.height()/2; painter->setPen(QPen(option->palette.background().color().darker(110))); painter->drawLine(rect.topLeft().x() + margin , rect.topLeft().y() + offset, rect.topRight().x() - margin, rect.topRight().y() + offset); } } break; case PE_IndicatorToolBarHandle: { bool horizontal = option->state & State_Horizontal; painter->save(); QPainterPath path; int x = option->rect.x() + horizontal ? 2 : 6; int y = option->rect.y() + horizontal ? 6 : 2; static const int RectHeight = 2; if (horizontal) { while (y < option->rect.height() - RectHeight - 6) { path.moveTo(x, y); path.addRect(x, y, RectHeight, RectHeight); y += 6; } } else { while (x < option->rect.width() - RectHeight - 6) { path.moveTo(x, y); path.addRect(x, y, RectHeight, RectHeight); x += 6; } } painter->setPen(Qt::NoPen); QColor dark = Utils::StyleHelper::borderColor(); dark.setAlphaF(0.4); QColor light = Utils::StyleHelper::baseColor(); light.setAlphaF(0.4); painter->fillPath(path, light); painter->save(); painter->translate(1, 1); painter->fillPath(path, dark); painter->restore(); painter->translate(3, 3); painter->fillPath(path, light); painter->translate(1, 1); painter->fillPath(path, dark); painter->restore(); } break; case PE_IndicatorArrowUp: case PE_IndicatorArrowDown: case PE_IndicatorArrowRight: case PE_IndicatorArrowLeft: { // From windowsstyle but modified to enable AA if (option->rect.width() <= 1 || option->rect.height() <= 1) break; QRect r = option->rect; int size = qMin(r.height(), r.width()); QPixmap pixmap; QString pixmapName; pixmapName.sprintf("%s-%s-%d-%d-%d-%lld", "$qt_ia", metaObject()->className(), uint(option->state), element, size, option->palette.cacheKey()); if (!QPixmapCache::find(pixmapName, pixmap)) { int border = size/5; int sqsize = 2*(size/2); QImage image(sqsize, sqsize, QImage::Format_ARGB32); image.fill(Qt::transparent); QPainter imagePainter(&image); imagePainter.setRenderHint(QPainter::Antialiasing, true); imagePainter.translate(0.5, 0.5); QPolygon a; switch (element) { case PE_IndicatorArrowUp: a.setPoints(3, border, sqsize/2, sqsize/2, border, sqsize - border, sqsize/2); break; case PE_IndicatorArrowDown: a.setPoints(3, border, sqsize/2, sqsize/2, sqsize - border, sqsize - border, sqsize/2); break; case PE_IndicatorArrowRight: a.setPoints(3, sqsize - border, sqsize/2, sqsize/2, border, sqsize/2, sqsize - border); break; case PE_IndicatorArrowLeft: a.setPoints(3, border, sqsize/2, sqsize/2, border, sqsize/2, sqsize - border); break; default: break; } int bsx = 0; int bsy = 0; if (option->state & State_Sunken) { bsx = pixelMetric(PM_ButtonShiftHorizontal); bsy = pixelMetric(PM_ButtonShiftVertical); } QRect bounds = a.boundingRect(); int sx = sqsize / 2 - bounds.center().x() - 1; int sy = sqsize / 2 - bounds.center().y() - 1; imagePainter.translate(sx + bsx, sy + bsy); if (!(option->state & State_Enabled)) { QColor foreGround(150, 150, 150, 150); imagePainter.setBrush(option->palette.mid().color()); imagePainter.setPen(option->palette.mid().color()); } else { QColor shadow(0, 0, 0, 100); imagePainter.translate(0, 1); imagePainter.setPen(shadow); imagePainter.setBrush(shadow); QColor foreGround(255, 255, 255, 210); imagePainter.drawPolygon(a); imagePainter.translate(0, -1); imagePainter.setPen(foreGround); imagePainter.setBrush(foreGround); } imagePainter.drawPolygon(a); imagePainter.end(); pixmap = QPixmap::fromImage(image); QPixmapCache::insert(pixmapName, pixmap); } int xOffset = r.x() + (r.width() - size)/2; int yOffset = r.y() + (r.height() - size)/2; painter->drawPixmap(xOffset, yOffset, pixmap); } break; default: d->style->drawPrimitive(element, option, painter, widget); break; } } void ManhattanStyle::drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const { if (!panelWidget(widget)) return d->style->drawControl(element, option, painter, widget); switch (element) { case CE_MenuBarItem: painter->save(); if (const QStyleOptionMenuItem *mbi = qstyleoption_cast(option)) { QColor highlightOutline = Utils::StyleHelper::borderColor().lighter(120); bool act = mbi->state & State_Selected && mbi->state & State_Sunken; bool dis = !(mbi->state & State_Enabled); Utils::StyleHelper::menuGradient(painter, option->rect, option->rect); QStyleOptionMenuItem item = *mbi; item.rect = mbi->rect; QPalette pal = mbi->palette; pal.setBrush(QPalette::ButtonText, dis ? Qt::gray : Qt::black); item.palette = pal; QCommonStyle::drawControl(element, &item, painter, widget); QRect r = option->rect; if (act) { // Fill| QColor baseColor = Utils::StyleHelper::baseColor(); QLinearGradient grad(option->rect.topLeft(), option->rect.bottomLeft()); grad.setColorAt(0, baseColor.lighter(120)); grad.setColorAt(1, baseColor.lighter(130)); painter->fillRect(option->rect.adjusted(1, 1, -1, 0), grad); // Outline painter->setPen(QPen(highlightOutline, 0)); painter->drawLine(QPoint(r.left(), r.top() + 1), QPoint(r.left(), r.bottom())); painter->drawLine(QPoint(r.right(), r.top() + 1), QPoint(r.right(), r.bottom())); painter->drawLine(QPoint(r.left() + 1, r.top()), QPoint(r.right() - 1, r.top())); highlightOutline.setAlpha(60); painter->setPen(QPen(highlightOutline, 0)); painter->drawPoint(r.topLeft()); painter->drawPoint(r.topRight()); QPalette pal = mbi->palette; uint alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine; if (!styleHint(SH_UnderlineShortcut, mbi, widget)) alignment |= Qt::TextHideMnemonic; pal.setBrush(QPalette::Text, dis ? Qt::gray : QColor(0, 0, 0, 60)); drawItemText(painter, item.rect.translated(0, 1), alignment, pal, mbi->state & State_Enabled, mbi->text, QPalette::Text); pal.setBrush(QPalette::Text, dis ? Qt::gray : Qt::white); drawItemText(painter, item.rect, alignment, pal, mbi->state & State_Enabled, mbi->text, QPalette::Text); } } painter->restore(); break; case CE_ComboBoxLabel: if (const QStyleOptionComboBox *cb = qstyleoption_cast(option)) { if (panelWidget(widget)) { QRect editRect = subControlRect(CC_ComboBox, cb, SC_ComboBoxEditField, widget); QPalette customPal = cb->palette; if (!cb->currentIcon.isNull()) { QIcon::Mode mode = cb->state & State_Enabled ? QIcon::Normal : QIcon::Disabled; QPixmap pixmap = cb->currentIcon.pixmap(cb->iconSize, mode); QRect iconRect(editRect); iconRect.setWidth(cb->iconSize.width() + 4); iconRect = alignedRect(cb->direction, Qt::AlignLeft | Qt::AlignVCenter, iconRect.size(), editRect); if (cb->editable) painter->fillRect(iconRect, customPal.brush(QPalette::Base)); drawItemPixmap(painter, iconRect, Qt::AlignCenter, pixmap); if (cb->direction == Qt::RightToLeft) editRect.translate(-4 - cb->iconSize.width(), 0); else editRect.translate(cb->iconSize.width() + 4, 0); // Reserve some space for the down-arrow editRect.adjust(0, 0, -13, 0); } customPal.setBrush(QPalette::All, QPalette::ButtonText, QColor(0, 0, 0, 70)); QString text = option->fontMetrics.elidedText(cb->currentText, Qt::ElideRight, editRect.width()); drawItemText(painter, editRect.translated(0, 1), visualAlignment(option->direction, Qt::AlignLeft | Qt::AlignVCenter), customPal, cb->state & State_Enabled, text, QPalette::ButtonText); customPal.setBrush(QPalette::All, QPalette::ButtonText, Utils::StyleHelper::panelTextColor()); drawItemText(painter, editRect, visualAlignment(option->direction, Qt::AlignLeft | Qt::AlignVCenter), customPal, cb->state & State_Enabled, text, QPalette::ButtonText); } else { d->style->drawControl(element, option, painter, widget); } } break; case CE_SizeGrip: { painter->save(); QColor dark = Qt::white; dark.setAlphaF(0.1); int x, y, w, h; option->rect.getRect(&x, &y, &w, &h); int sw = qMin(h, w); if (h > w) painter->translate(0, h - w); else painter->translate(w - h, 0); int sx = x; int sy = y; int s = 4; painter->setPen(dark); if (option->direction == Qt::RightToLeft) { sx = x + sw; for (int i = 0; i < 4; ++i) { painter->drawLine(x, sy, sx, sw); sx -= s; sy += s; } } else { for (int i = 0; i < 4; ++i) { painter->drawLine(sx, sw, sw, sy); sx += s; sy += s; } } painter->restore(); } break; case CE_MenuBarEmptyArea: { Utils::StyleHelper::menuGradient(painter, option->rect, option->rect); painter->save(); painter->setPen(Utils::StyleHelper::borderColor()); painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight()); painter->restore(); } break; case CE_ToolBar: { QString key; key.sprintf("mh_toolbar %d %d %d", option->rect.width(), option->rect.height(), Utils::StyleHelper::baseColor().rgb());; QPixmap pixmap; QPainter *p = painter; QRect rect = option->rect; if (Utils::StyleHelper::usePixmapCache() && !QPixmapCache::find(key, pixmap)) { pixmap = QPixmap(option->rect.size()); p = new QPainter(&pixmap); rect = QRect(0, 0, option->rect.width(), option->rect.height()); } bool horizontal = option->state & State_Horizontal; // Map offset for global window gradient QPoint offset = widget->window()->mapToGlobal(option->rect.topLeft()) - widget->mapToGlobal(option->rect.topLeft()); QRect gradientSpan; if (widget) { gradientSpan = QRect(offset, widget->window()->size()); } if (horizontal) Utils::StyleHelper::horizontalGradient(p, gradientSpan, rect); else Utils::StyleHelper::verticalGradient(p, gradientSpan, rect); painter->setPen(Utils::StyleHelper::borderColor()); if (horizontal) { // Note: This is a hack to determine if the // toolbar should draw the top or bottom outline // (needed for the find toolbar for instance) QColor lighter(255, 255, 255, 40); if (widget && widget->property("topBorder").toBool()) { p->drawLine(rect.topLeft(), rect.topRight()); p->setPen(lighter); p->drawLine(rect.topLeft() + QPoint(0, 1), rect.topRight() + QPoint(0, 1)); } else { p->drawLine(rect.bottomLeft(), rect.bottomRight()); p->setPen(lighter); p->drawLine(rect.topLeft(), rect.topRight()); } } else { p->drawLine(rect.topLeft(), rect.bottomLeft()); p->drawLine(rect.topRight(), rect.bottomRight()); } if (Utils::StyleHelper::usePixmapCache() && !QPixmapCache::find(key, pixmap)) { painter->drawPixmap(rect.topLeft(), pixmap); p->end(); delete p; QPixmapCache::insert(key, pixmap); } } break; default: d->style->drawControl(element, option, painter, widget); break; } } void ManhattanStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const { if (!panelWidget(widget)) return d->style->drawComplexControl(control, option, painter, widget); QRect rect = option->rect; switch (control) { case CC_ToolButton: if (const QStyleOptionToolButton *toolbutton = qstyleoption_cast(option)) { QRect button, menuarea; button = subControlRect(control, toolbutton, SC_ToolButton, widget); menuarea = subControlRect(control, toolbutton, SC_ToolButtonMenu, widget); State bflags = toolbutton->state; if (bflags & State_AutoRaise) { if (!(bflags & State_MouseOver)) { bflags &= ~State_Raised; } } State mflags = bflags; if (toolbutton->state & State_Sunken) { if (toolbutton->activeSubControls & SC_ToolButton) bflags |= State_Sunken; if (toolbutton->activeSubControls & SC_ToolButtonMenu) mflags |= State_Sunken; } QStyleOption tool(0); tool.palette = toolbutton->palette; if (toolbutton->subControls & SC_ToolButton) { tool.rect = button; tool.state = bflags; drawPrimitive(PE_PanelButtonTool, &tool, painter, widget); } if (toolbutton->state & State_HasFocus) { QStyleOptionFocusRect fr; fr.QStyleOption::operator=(*toolbutton); fr.rect.adjust(3, 3, -3, -3); if (toolbutton->features & QStyleOptionToolButton::MenuButtonPopup) fr.rect.adjust(0, 0, -pixelMetric(QStyle::PM_MenuButtonIndicator, toolbutton, widget), 0); QPen oldPen = painter->pen(); QColor focusColor = Utils::StyleHelper::panelTextColor(); focusColor.setAlpha(120); QPen outline(focusColor, 1); outline.setStyle(Qt::DotLine); painter->setPen(outline); QRect r = option->rect.adjusted(2, 2, -2, -2); painter->drawRect(r); painter->setPen(oldPen); } QStyleOptionToolButton label = *toolbutton; label.palette = panelPalette(option->palette); int fw = pixelMetric(PM_DefaultFrameWidth, option, widget); label.rect = button.adjusted(fw, fw, -fw, -fw); drawControl(CE_ToolButtonLabel, &label, painter, widget); if (toolbutton->subControls & SC_ToolButtonMenu) { tool.state = mflags; tool.rect = menuarea.adjusted(1, 1, -1, -1); if (mflags & (State_Sunken | State_On | State_Raised)) { painter->setPen(Qt::gray); painter->drawLine(tool.rect.topLeft(), tool.rect.bottomLeft()); if (mflags & (State_Sunken)) { QColor shade(0, 0, 0, 50); painter->fillRect(tool.rect.adjusted(0, -1, 1, 1), shade); } #ifndef Q_WS_MAC else if (mflags & (State_MouseOver)) { QColor shade(255, 255, 255, 50); painter->fillRect(tool.rect.adjusted(0, -1, 1, 1), shade); } #endif } tool.rect = tool.rect.adjusted(2, 2, -2, -2); drawPrimitive(PE_IndicatorArrowDown, &tool, painter, widget); } else if (toolbutton->features & QStyleOptionToolButton::HasMenu) { int arrowSize = 6; QRect ir = toolbutton->rect.adjusted(1, 1, -1, -1); QStyleOptionToolButton newBtn = *toolbutton; newBtn.palette = panelPalette(option->palette); newBtn.rect = QRect(ir.right() - arrowSize - 1, ir.height() - arrowSize - 2, arrowSize, arrowSize); drawPrimitive(PE_IndicatorArrowDown, &newBtn, painter, widget); } } break; case CC_ComboBox: if (const QStyleOptionComboBox *cb = qstyleoption_cast(option)) { painter->save(); bool isEmpty = cb->currentText.isEmpty() && cb->currentIcon.isNull(); bool reverse = option->direction == Qt::RightToLeft; // Draw tool button QLinearGradient grad(option->rect.topRight(), option->rect.bottomRight()); grad.setColorAt(0, QColor(255, 255, 255, 20)); grad.setColorAt(0.4, QColor(255, 255, 255, 60)); grad.setColorAt(0.7, QColor(255, 255, 255, 50)); grad.setColorAt(1, QColor(255, 255, 255, 40)); painter->setPen(QPen(grad, 0)); painter->drawLine(rect.topRight(), rect.bottomRight()); grad.setColorAt(0, QColor(0, 0, 0, 30)); grad.setColorAt(0.4, QColor(0, 0, 0, 70)); grad.setColorAt(0.7, QColor(0, 0, 0, 70)); grad.setColorAt(1, QColor(0, 0, 0, 40)); painter->setPen(QPen(grad, 0)); if (!reverse) painter->drawLine(rect.topRight() - QPoint(1,0), rect.bottomRight() - QPoint(1,0)); else painter->drawLine(rect.topLeft(), rect.bottomLeft()); QStyleOption toolbutton = *option; if (isEmpty) toolbutton.state &= ~(State_Enabled | State_Sunken); painter->save(); painter->setClipRect(toolbutton.rect.adjusted(0, 0, -2, 0)); drawPrimitive(PE_PanelButtonTool, &toolbutton, painter, widget); painter->restore(); // Draw arrow int menuButtonWidth = 12; int left = !reverse ? rect.right() - menuButtonWidth : rect.left(); int right = !reverse ? rect.right() : rect.left() + menuButtonWidth; QRect arrowRect((left + right) / 2 + (reverse ? 6 : -6), rect.center().y() - 3, 9, 9); if (option->state & State_On) arrowRect.translate(d->style->pixelMetric(PM_ButtonShiftHorizontal, option, widget), d->style->pixelMetric(PM_ButtonShiftVertical, option, widget)); QStyleOption arrowOpt = *option; arrowOpt.rect = arrowRect; if (isEmpty) arrowOpt.state &= ~(State_Enabled | State_Sunken); if (styleHint(SH_ComboBox_Popup, option, widget)) { arrowOpt.rect.translate(0, -3); drawPrimitive(PE_IndicatorArrowUp, &arrowOpt, painter, widget); arrowOpt.rect.translate(0, 6); drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, painter, widget); } else { drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, painter, widget); } painter->restore(); } break; default: d->style->drawComplexControl(control, option, painter, widget); break; } } // Mac style reimplements this to control the // focus widget among other things bool ManhattanStyle::event(QEvent *e) { Q_ASSERT(d->style); return d->style->event(e); }