diff -r 41300fa6a67c -r 2f34d5167611 src/gui/styles/qs60style.cpp --- a/src/gui/styles/qs60style.cpp Tue Feb 02 00:43:10 2010 +0200 +++ b/src/gui/styles/qs60style.cpp Fri Apr 16 15:50:13 2010 +0300 @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** @@ -68,6 +68,10 @@ #include "qtoolbutton.h" #include "qfocusframe.h" #include "qformlayout.h" +#include "qradiobutton.h" +#include "qcheckbox.h" +#include "qdesktopwidget.h" +#include "qprogressbar.h" #include "private/qtoolbarextension_p.h" #include "private/qcombobox_p.h" @@ -88,10 +92,10 @@ const layoutHeader QS60StylePrivate::m_layoutHeaders[] = { // *** generated layout data *** -{240,320,1,15,"QVGA Landscape"}, -{320,240,1,15,"QVGA Portrait"}, -{360,640,1,15,"NHD Landscape"}, -{640,360,1,15,"NHD Portrait"}, +{240,320,1,16,"QVGA Landscape"}, +{320,240,1,16,"QVGA Portrait"}, +{360,640,1,16,"NHD Landscape"}, +{640,360,1,16,"NHD Portrait"}, {352,800,1,12,"E90 Landscape"} // *** End of generated data *** }; @@ -100,10 +104,10 @@ const short QS60StylePrivate::data[][MAX_PIXELMETRICS] = { // *** generated pixel metrics *** -{5,0,-909,0,0,2,0,0,-1,7,12,19,13,13,6,200,-909,-909,-909,20,13,2,0,0,21,7,18,-909,3,3,1,-909,-909,0,1,0,0,12,20,15,15,18,18,1,115,18,0,-909,-909,-909,-909,0,0,16,2,-909,0,0,-909,16,-909,-909,-909,-909,32,18,55,24,55,3,3,4,9,13,-909,5,51,11,5,0,3,3,6,8,3,3,-909,2,-909,-909,-909,-909,5,5,3,1}, -{5,0,-909,0,0,1,0,0,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,8,27,-909,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,4,4,5,10,15,-909,5,58,13,5,0,4,4,7,9,4,4,-909,2,-909,-909,-909,-909,6,6,3,1}, -{7,0,-909,0,0,2,0,0,-1,25,69,28,19,19,9,258,-909,-909,-909,23,19,26,0,0,32,25,72,-909,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,5,5,6,8,19,-909,7,74,19,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1}, -{7,0,-909,0,0,2,0,0,-1,25,68,28,19,19,9,258,-909,-909,-909,31,19,6,0,0,32,25,60,-909,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,96,35,96,5,5,6,8,19,-909,7,74,22,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1}, +{5,0,-909,0,0,2,0,0,-1,7,12,19,13,13,6,200,-909,-909,-909,20,13,2,0,0,21,7,18,-909,3,3,1,-909,-909,0,1,0,0,12,20,15,15,18,18,1,115,18,0,-909,-909,-909,-909,0,0,16,2,-909,0,0,-909,16,-909,-909,-909,-909,32,18,55,24,55,4,4,4,9,13,-909,5,51,11,5,0,3,3,6,8,3,3,-909,2,-909,-909,-909,-909,5,5,3,1}, +{5,0,-909,0,0,1,0,0,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,8,27,-909,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,3,3,5,10,15,-909,5,58,13,5,0,4,4,7,9,4,4,-909,2,-909,-909,-909,-909,6,6,3,1}, +{7,0,-909,0,0,2,0,0,-1,25,69,28,19,19,9,258,-909,-909,-909,23,19,26,0,0,32,25,72,-909,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,13,13,6,8,19,-909,7,74,19,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1}, +{7,0,-909,0,0,2,0,0,-1,25,68,28,19,19,9,258,-909,-909,-909,31,19,6,0,0,32,25,60,-909,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,96,35,96,12,12,6,8,19,-909,7,74,22,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1}, {7,0,-909,0,0,2,0,0,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,7,32,-909,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,6,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,5,6,8,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1} // *** End of generated data *** }; @@ -116,6 +120,8 @@ // theme palette QPalette *QS60StylePrivate::m_themePalette = 0; +qint64 QS60StylePrivate::m_webPaletteKey = 0; + const struct QS60StylePrivate::frameElementCenter QS60StylePrivate::m_frameElementsData[] = { {SE_ButtonNormal, QS60StyleEnums::SP_QsnFrButtonTbCenter}, {SE_ButtonPressed, QS60StyleEnums::SP_QsnFrButtonTbCenterPressed}, @@ -285,6 +291,9 @@ case SE_Editor: drawFrame(SF_FrameLineEdit, painter, rect, flags | SF_PointNorth); break; + case SE_DropArea: + drawPart(QS60StyleEnums::SP_QgnGrafOrgBgGrid, painter, rect, flags | SF_PointNorth); + break; default: break; } @@ -310,8 +319,8 @@ QColor hsvColor = retColor.toHsv(); int colorSat = hsvColor.saturation(); int colorVal = hsvColor.value(); - colorSat = (colorSat!=0) ? (colorSat>>1) : 128; - colorVal = (colorVal!=0) ? (colorVal>>1) : 128; + colorSat = (colorSat != 0) ? (colorSat >> 1) : 128; + colorVal = (colorVal != 0) ? (colorVal >> 1) : 128; hsvColor.setHsv(hsvColor.hue(), colorSat, colorVal); retColor = hsvColor.toRgb(); } @@ -339,11 +348,12 @@ bool QS60StylePrivate::drawsOwnThemeBackground(const QWidget *widget) { - return qobject_cast (widget); + return (widget ? (widget->windowType() == Qt::Dialog) : false); } QFont QS60StylePrivate::s60Font( - QS60StyleEnums::FontCategories fontCategory, int pointSize) const + QS60StyleEnums::FontCategories fontCategory, + int pointSize, bool resolveFontSize) const { QFont result; int actualPointSize = pointSize; @@ -356,7 +366,7 @@ Q_ASSERT(actualPointSize > 0); const QPair key(fontCategory, actualPointSize); if (!m_mappedFontsCache.contains(key)) { - result = s60Font_specific(fontCategory, actualPointSize); + result = s60Font_specific(fontCategory, actualPointSize, resolveFontSize); m_mappedFontsCache.insert(key, result); } else { result = m_mappedFontsCache.value(key); @@ -372,7 +382,6 @@ case CC_LayoutChange: // when layout changes, the colors remain in cache, but graphics and fonts can change m_mappedFontsCache.clear(); - deleteBackground(); QPixmapCache::clear(); break; case CC_ThemeChange: @@ -400,10 +409,10 @@ if (!cachedColorExists) { const int frameCornerWidth = pixelMetric(PM_Custom_FrameCornerWidth); const int frameCornerHeight = pixelMetric(PM_Custom_FrameCornerHeight); - Q_ASSERT(2*frameCornerWidth<32); - Q_ASSERT(2*frameCornerHeight<32); + Q_ASSERT(2 * frameCornerWidth < 32); + Q_ASSERT(2 * frameCornerHeight < 32); - const QImage frameImage = QS60StylePrivate::frame(frame, QSize(32,32)).toImage(); + const QImage frameImage = QS60StylePrivate::frame(frame, QSize(32, 32)).toImage(); Q_ASSERT(frameImage.bytesPerLine() > 0); if (frameImage.isNull()) return Qt::black; @@ -418,14 +427,14 @@ int skips = 0; int estimations = 0; - const int topBorderLastPixel = frameCornerHeight*frameImage.width()-1; - const int bottomBorderFirstPixel = frameImage.width()*frameImage.height()-frameCornerHeight*frameImage.width()-1; - const int rightBorderFirstPixel = frameImage.width()-frameCornerWidth; + const int topBorderLastPixel = frameCornerHeight*frameImage.width() - 1; + const int bottomBorderFirstPixel = frameImage.width() * frameImage.height() - frameCornerHeight*frameImage.width() - 1; + const int rightBorderFirstPixel = frameImage.width() - frameCornerWidth; const int leftBorderLastPixel = frameCornerWidth; while ((skips + estimations) < pixels) { - if ((skips+estimations) > topBorderLastPixel && - (skips+estimations) < bottomBorderFirstPixel) { + if ((skips + estimations) > topBorderLastPixel && + (skips + estimations) < bottomBorderFirstPixel) { for (int rowIndex = 0; rowIndex < frameImage.width(); rowIndex++) { if (rowIndex > leftBorderLastPixel && rowIndex < rightBorderFirstPixel) { @@ -530,18 +539,18 @@ endRect = startRect.translated(rect.width() - startRect.width(), 0); middleRect.adjust(startRect.width(), 0, -startRect.width(), 0); if (startRect.bottomRight().x() > endRect.topLeft().x()) { - const int overlap = (startRect.bottomRight().x() - endRect.topLeft().x())>>1; - startRect.setWidth(startRect.width()-overlap); - endRect.adjust(overlap,0,0,0); + const int overlap = (startRect.bottomRight().x() - endRect.topLeft().x()) >> 1; + startRect.setWidth(startRect.width() - overlap); + endRect.adjust(overlap, 0, 0, 0); } } else { startRect.setHeight(qMin((rect.height() >> 1) - 1, startRect.height())); endRect = startRect.translated(0, rect.height() - startRect.height()); middleRect.adjust(0, startRect.height(), 0, -startRect.height()); if (startRect.topRight().y() > endRect.bottomLeft().y()) { - const int overlap = (startRect.topRight().y() - endRect.bottomLeft().y())>>1; - startRect.setHeight(startRect.height()-overlap); - endRect.adjust(0,overlap,0,0); + const int overlap = (startRect.topRight().y() - endRect.bottomLeft().y()) >> 1; + startRect.setHeight(startRect.height() - overlap); + endRect.adjust(0, overlap, 0, 0); } } @@ -564,9 +573,11 @@ const QSize &size, QPainter *painter, SkinElementFlags flags) { QPixmap result; + const int animationFrame = (flags & SF_Animation) ? currentAnimationFrame(part) : 0; + const QString cacheKey = - QString::fromLatin1("S60Style: SkinParts=%1 QSize=%2|%3 SkinPartFlags=%4") - .arg((int)part).arg(size.width()).arg(size.height()).arg((int)flags); + QString::fromLatin1("S60Style: SkinParts=%1 QSize=%2|%3 SkinPartFlags=%4 AnimationFrame=%5") + .arg((int)part).arg(size.width()).arg(size.height()).arg((int)flags).arg(animationFrame); if (!QPixmapCache::find(cacheKey, result)) { result = QS60StylePrivate::part(part, size, painter, flags); QPixmapCache::insert(cacheKey, result); @@ -621,8 +632,10 @@ fontCategory = QS60StyleEnums::FC_Title; } if (fontCategory != QS60StyleEnums::FC_Undefined) { + const bool resolveFontSize = widget->testAttribute(Qt::WA_SetFont) + && (widget->font().resolve() & QFont::SizeResolved); const QFont suggestedFont = - s60Font(fontCategory, widget->font().pointSizeF()); + s60Font(fontCategory, widget->font().pointSizeF(), resolveFontSize); widget->setFont(suggestedFont); } } @@ -670,8 +683,7 @@ s60Color(QS60StyleEnums::CL_QsnHighlightColors, 2, 0)); // set background image as a texture brush palette->setBrush(QPalette::Window, backgroundTexture()); - // set these as transparent so that styled full screen theme background is visible - palette->setColor(QPalette::AlternateBase, Qt::transparent); + // set as transparent so that styled full screen theme background is visible palette->setBrush(QPalette::Base, Qt::transparent); // set button and tooltipbase based on pixel colors const QColor buttonColor = colorFromFrameGraphics(SF_ButtonNormal); @@ -683,6 +695,9 @@ palette->setColor(QPalette::Midlight, palette->color(QPalette::Button).lighter(125)); palette->setColor(QPalette::Mid, palette->color(QPalette::Button).darker(150)); palette->setColor(QPalette::Shadow, Qt::black); + QColor alternateBase = palette->light().color(); + alternateBase.setAlphaF(0.8); + palette->setColor(QPalette::AlternateBase, alternateBase); QApplication::setPalette(*palette); //calling QApplication::setPalette clears palette hash setThemePaletteHash(palette); @@ -773,6 +788,11 @@ QApplication::setPalette(widgetPalette, "QComboBox"); widgetPalette = *palette; + widgetPalette.setColor(QPalette::WindowText, s60Color(QS60StyleEnums::CL_QsnTextColors, 7, 0)); + QApplication::setPalette(widgetPalette, "QRadioButton"); + QApplication::setPalette(widgetPalette, "QCheckBox"); + widgetPalette = *palette; + widgetPalette.setColor(QPalette::WindowText, mainAreaTextColor); widgetPalette.setColor(QPalette::Button, QApplication::palette().color(QPalette::Button)); widgetPalette.setColor(QPalette::Dark, mainAreaTextColor.darker()); @@ -789,8 +809,12 @@ QPalette webPalette = *palette; webPalette.setColor(QPalette::WindowText, Qt::black); webPalette.setColor(QPalette::Text, Qt::black); + webPalette.setBrush(QPalette::Base, Qt::white); + QApplication::setPalette(webPalette, "QWebView"); QApplication::setPalette(webPalette, "QGraphicsWebView"); + + m_webPaletteKey = webPalette.cacheKey(); } QSize QS60StylePrivate::partSize(QS60StyleEnums::SkinParts part, SkinElementFlags flags) @@ -809,15 +833,15 @@ case QS60StyleEnums::SP_QgnGrafTabActiveL: //Returned QSize for tabs must not be square, but narrow rectangle with width:height //ratio of 1:2 for horizontal tab bars (and 2:1 for vertical ones). - result.setWidth(result.height()>>1); + result.setWidth(result.height() >> 1); break; - + case QS60StyleEnums::SP_QgnGrafNsliderEndLeft: case QS60StyleEnums::SP_QgnGrafNsliderEndRight: case QS60StyleEnums::SP_QgnGrafNsliderMiddle: - result.setWidth(result.height()>>1); + result.setWidth(result.height() >> 1); break; - + case QS60StyleEnums::SP_QgnGrafNsliderMarker: case QS60StyleEnums::SP_QgnGrafNsliderMarkerSelected: result.scale(pixelMetric(QStyle::PM_SliderLength), @@ -829,15 +853,18 @@ result.setWidth(pixelMetric(PM_Custom_FrameCornerWidth)); break; - case QS60StyleEnums::SP_QsnCpScrollHandleBottomPressed: case QS60StyleEnums::SP_QsnCpScrollHandleTopPressed: - case QS60StyleEnums::SP_QsnCpScrollHandleMiddlePressed: case QS60StyleEnums::SP_QsnCpScrollBgBottom: - case QS60StyleEnums::SP_QsnCpScrollBgMiddle: case QS60StyleEnums::SP_QsnCpScrollBgTop: case QS60StyleEnums::SP_QsnCpScrollHandleBottom: + case QS60StyleEnums::SP_QsnCpScrollHandleTop: + case QS60StyleEnums::SP_QsnCpScrollHandleBottomPressed: + result.setHeight(pixelMetric(QStyle::PM_ScrollBarExtent)); + result.setWidth(pixelMetric(QStyle::PM_ScrollBarExtent)); + break; + case QS60StyleEnums::SP_QsnCpScrollHandleMiddlePressed: + case QS60StyleEnums::SP_QsnCpScrollBgMiddle: case QS60StyleEnums::SP_QsnCpScrollHandleMiddle: - case QS60StyleEnums::SP_QsnCpScrollHandleTop: result.setHeight(pixelMetric(QStyle::PM_ScrollBarExtent)); result.setWidth(pixelMetric(QStyle::PM_ScrollBarSliderMin)); break; @@ -875,8 +902,11 @@ return result; } -bool QS60StylePrivate::canDrawThemeBackground(const QBrush &backgroundBrush) +bool QS60StylePrivate::canDrawThemeBackground(const QBrush &backgroundBrush, const QWidget *widget) { + // Always return true for web pages. + if (widget && m_webPaletteKey == QApplication::palette(widget).cacheKey()) + return true; //If brush is not changed from style's default values, draw theme graphics. return (backgroundBrush.color() == Qt::transparent || backgroundBrush.style() == Qt::NoBrush) ? true : false; @@ -920,10 +950,10 @@ horizontal ? QS60StylePrivate::SE_ScrollBarGrooveHorizontal : QS60StylePrivate::SE_ScrollBarGrooveVertical; QS60StylePrivate::drawSkinElement(grooveElement, painter, grooveRect, flags); - const QStyle::SubControls subControls = optionSlider->subControls; + const SubControls subControls = optionSlider->subControls; // select correct slider (horizontal/vertical/pressed) - const bool sliderPressed = ((optionSlider->state & QStyle::State_Sunken) && (subControls & SC_ScrollBarSlider)); + const bool sliderPressed = ((optionSlider->state & State_Sunken) && (subControls & SC_ScrollBarSlider)); const QS60StylePrivate::SkinElements handleElement = horizontal ? ( sliderPressed ? @@ -944,13 +974,13 @@ const bool horizontal = optionSlider->orientation == Qt::Horizontal; //Highlight -/* if (optionSlider->state & QStyle::State_HasFocus) +/* if (optionSlider->state & State_HasFocus) drawPrimitive(PE_FrameFocusRect, optionSlider, painter, widget);*/ - + //Groove graphics if (QS60StylePrivate::hasSliderGrooveGraphic()) { - const QS60StylePrivate::SkinElements grooveElement = horizontal ? - QS60StylePrivate::SE_SliderGrooveHorizontal : + const QS60StylePrivate::SkinElements grooveElement = horizontal ? + QS60StylePrivate::SE_SliderGrooveHorizontal : QS60StylePrivate::SE_SliderGrooveVertical; QS60StylePrivate::drawSkinElement(grooveElement, painter, sliderGroove, flags); } else { @@ -970,10 +1000,10 @@ //Handle graphics const QRect sliderHandle = subControlRect(control, optionSlider, SC_SliderHandle, widget); QS60StylePrivate::SkinElements handleElement; - if (optionSlider->state & QStyle::State_Sunken) + if (optionSlider->state & State_Sunken) handleElement = horizontal ? QS60StylePrivate::SE_SliderHandleSelectedHorizontal : QS60StylePrivate::SE_SliderHandleSelectedVertical; - else + else handleElement = horizontal ? QS60StylePrivate::SE_SliderHandleHorizontal : QS60StylePrivate::SE_SliderHandleVertical; QS60StylePrivate::drawSkinElement(handleElement, painter, sliderHandle, flags); @@ -992,10 +1022,11 @@ buttonOption.QStyleOption::operator=(*cmb); const int maxHeight = cmbxFrame.height(); const int maxWidth = cmbxFrame.width() - cmbxEditField.width(); - const int topLeftPoint = direction ? cmbxEditField.right()+1 : cmbxEditField.left()+1-maxWidth; + const int topLeftPoint = direction ? + (cmbxEditField.right() + 1) : (cmbxEditField.left() + 1 - maxWidth); const QRect buttonRect(topLeftPoint, cmbxEditField.top(), maxWidth, maxHeight); buttonOption.rect = buttonRect; - buttonOption.state = cmb->state & (State_Enabled | State_MouseOver); + buttonOption.state = cmb->state; drawPrimitive(PE_PanelButtonCommand, &buttonOption, painter, widget); // draw label background - label itself is drawn separately @@ -1017,102 +1048,62 @@ #ifndef QT_NO_TOOLBUTTON case CC_ToolButton: if (const QStyleOptionToolButton *toolBtn = qstyleoption_cast(option)) { - const State bflags = toolBtn->state; + State bflags = toolBtn->state & ~State_Sunken; + + if (bflags & State_AutoRaise) { + if (!(bflags & State_MouseOver) || !(bflags & State_Enabled)) { + bflags &= ~State_Raised; + } + } + State mflags = bflags; + if (toolBtn->state & State_Sunken) { + if (toolBtn->activeSubControls & SC_ToolButton) + bflags |= State_Sunken; + mflags |= State_Sunken; + } + const QRect button(subControlRect(control, toolBtn, SC_ToolButton, widget)); QRect menuRect = QRect(); if (toolBtn->subControls & SC_ToolButtonMenu) menuRect = subControlRect(control, toolBtn, SC_ToolButtonMenu, widget); - QStyleOptionToolButton toolButton = *toolBtn; - - if (sub&SC_ToolButton) { + if (toolBtn->subControls & SC_ToolButton) { QStyleOption tool(0); tool.palette = toolBtn->palette; - // Check if toolbutton is in toolbar. - QToolBar *toolBar = 0; - if (widget) - toolBar = qobject_cast(widget->parentWidget()); - - if (bflags & (State_Sunken | State_On | State_Raised)) { + if (bflags & (State_Sunken | State_On | State_Raised | State_Enabled)) { tool.rect = button.unite(menuRect); tool.state = bflags; - - // todo: I'd like to move extension button next to where last button is - // however, the painter seems to want to clip the button rect even if I turn of the clipping. - if (toolBar && (qobject_cast(widget))){ - /*QList actionList = toolBar->actions(); - const int actionCount = actionList.count(); - const int toolbarWidth = toolBar->width(); - const int extButtonWidth = pixelMetric(PM_ToolBarExtensionExtent, option, widget); - const int toolBarButtonWidth = pixelMetric(PM_ToolBarIconSize, option, widget); - const int frame = pixelMetric(PM_ToolBarFrameWidth, option, widget); - const int margin = pixelMetric(PM_ToolBarItemMargin, option, widget); - const int border = frame + margin; - const int spacing = pixelMetric(PM_ToolBarItemSpacing, option, widget); - const int toolBarButtonArea = toolbarWidth - extButtonWidth - spacing - 2*border; - const int numberOfVisibleButtons = toolBarButtonArea / toolBarButtonWidth; - // new extension button place is after border and all the other visible buttons (with spacings) - const int newXForExtensionButton = numberOfVisibleButtons * toolBarButtonWidth + (numberOfVisibleButtons-1)*spacing + border; - painter->save(); - painter->setClipping(false); - tool.rect.translate(-newXForExtensionButton,0); - painter->restore();*/ - } - - if (toolBar){ - /*if (toolBar->orientation() == Qt::Vertical){ - // todo: I'd like to make all vertical buttons the same size, but again the painter - // prefers to use clipping for button rects, even though clipping has been set off. - painter->save(); - painter->setClipping(false); - - const int origWidth = tool.rect.width(); - const int newWidth = toolBar->width()-2*pixelMetric(PM_ToolBarFrameWidth, option, widget); - painter->translate(origWidth-newWidth,0); - tool.rect.translate(origWidth-tool.rect.width(),0); - tool.rect.setWidth(newWidth); - - if (option->state & QStyle::State_Sunken) - QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ToolBarButtonPressed, painter, tool.rect, flags); - else - QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ToolBarButton, painter, tool.rect, flags); - - }*/ - if (option->state & QStyle::State_Sunken) - QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ToolBarButtonPressed, painter, tool.rect, flags); - else - QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ToolBarButton, painter, tool.rect, flags); - /* - if (toolBar->orientation() == Qt::Vertical) - painter->restore(); - */ - } else { - drawPrimitive(PE_PanelButtonTool, &tool, painter, widget); - } - - if (toolButton.subControls & SC_ToolButtonMenu) { - tool.rect = menuRect; - tool.state = bflags; - drawPrimitive(PE_IndicatorArrowDown, &tool, painter, widget); - } + const QToolButton *toolButtonWidget = qobject_cast(widget); + QS60StylePrivate::SkinElements element; + if (toolButtonWidget) + element = (toolButtonWidget->isDown()) ? QS60StylePrivate::SE_ToolBarButtonPressed : QS60StylePrivate::SE_ToolBarButton; + else + element = (option->state & State_Sunken) ? QS60StylePrivate::SE_ToolBarButtonPressed : QS60StylePrivate::SE_ToolBarButton; + QS60StylePrivate::drawSkinElement(element, painter, tool.rect, flags); + drawPrimitive(PE_PanelButtonTool, &tool, painter, widget); + } + if (toolBtn->subControls & SC_ToolButtonMenu) { + tool.rect = menuRect; + tool.state = mflags; + drawPrimitive(PE_IndicatorArrowDown, &tool, painter, widget); } } - + QStyleOptionToolButton toolButton = *toolBtn; if (toolBtn->features & QStyleOptionToolButton::Arrow) { - QStyle::PrimitiveElement pe; + PrimitiveElement pe; switch (toolBtn->arrowType) { case Qt::LeftArrow: - pe = QStyle::PE_IndicatorArrowLeft; + pe = PE_IndicatorArrowLeft; break; case Qt::RightArrow: - pe = QStyle::PE_IndicatorArrowRight; + pe = PE_IndicatorArrowRight; break; case Qt::UpArrow: - pe = QStyle::PE_IndicatorArrowUp; + pe = PE_IndicatorArrowUp; break; case Qt::DownArrow: - pe = QStyle::PE_IndicatorArrowDown; + pe = PE_IndicatorArrowDown; break; default: break; } @@ -1196,7 +1187,7 @@ // Draw frame const QRect textRect = subControlRect(CC_GroupBox, option, SC_GroupBoxLabel, widget); const QRect checkBoxRect = subControlRect(CC_GroupBox, option, SC_GroupBoxCheckBox, widget); - if (groupBox->subControls & QStyle::SC_GroupBoxFrame) { + if (groupBox->subControls & SC_GroupBoxFrame) { QStyleOptionFrameV2 frame; frame.QStyleOption::operator=(*groupBox); frame.features = groupBox->features; @@ -1207,14 +1198,14 @@ } // Draw title - if ((groupBox->subControls & QStyle::SC_GroupBoxLabel) && !groupBox->text.isEmpty()) { + if ((groupBox->subControls & SC_GroupBoxLabel) && !groupBox->text.isEmpty()) { const QColor textColor = groupBox->textColor; painter->save(); if (textColor.isValid()) painter->setPen(textColor); int alignment = int(groupBox->textAlignment); - if (!styleHint(QStyle::SH_UnderlineShortcut, option, widget)) + if (!styleHint(SH_UnderlineShortcut, option, widget)) alignment |= Qt::TextHideMnemonic; drawItemText(painter, textRect, Qt::TextShowMnemonic | Qt::AlignHCenter | Qt::AlignVCenter | alignment, @@ -1246,6 +1237,31 @@ Q_D(const QS60Style); const QS60StylePrivate::SkinElementFlags flags = (option->state & State_Enabled) ? QS60StylePrivate::SF_StateEnabled : QS60StylePrivate::SF_StateDisabled; switch (element) { + case CE_CheckBox: + case CE_RadioButton: + if (const QStyleOptionButton *btn = qstyleoption_cast(option)) { + bool isRadio = (element == CE_RadioButton); + // Highlight needs to be drawn first, as it goes "underneath" the text and indicator. + if (btn->state & State_HasFocus) { + QStyleOptionFocusRect fropt; + fropt.QStyleOption::operator=(*btn); + fropt.rect = subElementRect(isRadio ? SE_RadioButtonFocusRect + : SE_CheckBoxFocusRect, btn, widget); + drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget); + } + QStyleOptionButton subopt = *btn; + + subopt.rect = subElementRect(isRadio ? SE_RadioButtonIndicator + : SE_CheckBoxIndicator, btn, widget); + drawPrimitive(isRadio ? PE_IndicatorRadioButton : PE_IndicatorCheckBox, + &subopt, painter, widget); + subopt.rect = subElementRect(isRadio ? SE_RadioButtonContents + : SE_CheckBoxContents, btn, widget); + + drawControl(isRadio ? CE_RadioButtonLabel : CE_CheckBoxLabel, &subopt, painter, widget); + } + break; + case CE_PushButton: if (const QStyleOptionButton *btn = qstyleoption_cast(option)) { @@ -1258,13 +1274,13 @@ break; case CE_PushButtonBevel: if (const QStyleOptionButton *button = qstyleoption_cast(option)) { - const bool isDisabled = !(option->state & QStyle::State_Enabled); + const bool isDisabled = !(option->state & State_Enabled); const bool isFlat = button->features & QStyleOptionButton::Flat; QS60StyleEnums::SkinParts skinPart; QS60StylePrivate::SkinElements skinElement; if (!isDisabled) { - const bool isPressed = (option->state & QStyle::State_Sunken) || - (option->state & QStyle::State_On); + const bool isPressed = (option->state & State_Sunken) || + (option->state & State_On); if (isFlat) { skinPart = isPressed ? QS60StyleEnums::SP_QsnFrButtonTbCenterPressed : QS60StyleEnums::SP_QsnFrButtonTbCenter; @@ -1289,7 +1305,7 @@ if (const QStyleOptionToolButton *toolBtn = qstyleoption_cast(option)) { QStyleOptionToolButton optionToolButton = *toolBtn; - if (!optionToolButton.icon.isNull() && (optionToolButton.state & QStyle::State_Sunken) + if (!optionToolButton.icon.isNull() && (optionToolButton.state & State_Sunken) && (optionToolButton.state & State_Enabled)) { const QIcon::State state = optionToolButton.state & State_On ? QIcon::On : QIcon::Off; @@ -1348,8 +1364,8 @@ painter->save(); painter->setClipRect(voptAdj.rect); - const bool isSelected = (vopt->state & QStyle::State_Selected); - const bool hasFocus = (vopt->state & QStyle::State_HasFocus); + const bool isSelected = (vopt->state & State_Selected); + const bool hasFocus = (vopt->state & State_HasFocus); bool isScrollBarVisible = false; int scrollBarWidth = 0; @@ -1363,7 +1379,7 @@ } } - int rightValue = widget ? widget->contentsRect().right() : 0; + int rightValue = widget ? widget->contentsRect().right() : voptAdj.rect.right(); if (isScrollBarVisible) rightValue -= scrollBarWidth; @@ -1381,9 +1397,9 @@ const QModelIndex index = vopt->index; //todo: Draw cell background only once - for the first cell. QStyleOptionViewItemV4 voptAdj2 = voptAdj; - const QModelIndex indexFirst = itemView->model()->index(0,0); + const QModelIndex indexFirst = itemView->model()->index(0, 0); const QModelIndex indexLast = itemView->model()->index( - itemView->model()->rowCount()-1,itemView->model()->columnCount()-1); + itemView->model()->rowCount() - 1, itemView->model()->columnCount() -1); if (itemView->viewport()) voptAdj2.rect = QRect( itemView->visualRect(indexFirst).topLeft(), itemView->visualRect(indexLast).bottomRight()).intersect(itemView->viewport()->rect()); @@ -1423,8 +1439,8 @@ } // draw the icon - const QIcon::Mode mode = (voptAdj.state & QStyle::State_Enabled) ? QIcon::Normal : QIcon::Disabled; - const QIcon::State state = voptAdj.state & QStyle::State_Open ? QIcon::On : QIcon::Off; + const QIcon::Mode mode = (voptAdj.state & State_Enabled) ? QIcon::Normal : QIcon::Disabled; + const QIcon::State state = voptAdj.state & State_Open ? QIcon::On : QIcon::Off; voptAdj.icon.paint(painter, iconRect, voptAdj.decorationAlignment, mode, state); // Draw selection check mark. Show check mark only in multi selection modes. @@ -1436,29 +1452,29 @@ QStyleOptionViewItemV4 checkMarkOption(voptAdj); // Draw selection mark. - if (voptAdj.state & QStyle::State_Selected && !singleSelection) { + if (voptAdj.state & State_Selected && !singleSelection) { checkMarkOption.rect = selectionRect; - drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &checkMarkOption, painter, widget); + drawPrimitive(PE_IndicatorViewItemCheck, &checkMarkOption, painter, widget); if ( textRect.right() > selectionRect.left() ) textRect.setRight(selectionRect.left()); } else if (singleSelection && voptAdj.features & QStyleOptionViewItemV2::HasCheckIndicator && selectionRect.isValid()) { checkMarkOption.rect = selectionRect; - checkMarkOption.state = checkMarkOption.state & ~QStyle::State_HasFocus; + checkMarkOption.state = checkMarkOption.state & ~State_HasFocus; switch (vopt->checkState) { case Qt::Unchecked: - checkMarkOption.state |= QStyle::State_Off; + checkMarkOption.state |= State_Off; break; case Qt::PartiallyChecked: - checkMarkOption.state |= QStyle::State_NoChange; + checkMarkOption.state |= State_NoChange; break; case Qt::Checked: - checkMarkOption.state |= QStyle::State_On; + checkMarkOption.state |= State_On; break; } - drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &checkMarkOption, painter, widget); + drawPrimitive(PE_IndicatorViewItemCheck, &checkMarkOption, painter, widget); } } @@ -1483,7 +1499,7 @@ case CE_TabBarTabShape: if (const QStyleOptionTabV3 *optionTab = qstyleoption_cast(option)) { QStyleOptionTabV3 optionTabAdj = *optionTab; - const bool isSelected = optionTab->state & QStyle::State_Selected; + const bool isSelected = optionTab->state & State_Selected; const bool directionMirrored = (optionTab->direction == Qt::RightToLeft); QS60StylePrivate::SkinElements skinElement; switch (optionTab->shape) { @@ -1518,9 +1534,9 @@ skinElement==QS60StylePrivate::SE_TabBarTabSouthActive|| skinElement==QS60StylePrivate::SE_TabBarTabWestActive) { const int borderThickness = - QS60StylePrivate::pixelMetric(QStyle::PM_DefaultFrameWidth); + QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth); const int tabOverlap = - QS60StylePrivate::pixelMetric(QStyle::PM_TabBarTabOverlap) - borderThickness; + QS60StylePrivate::pixelMetric(PM_TabBarTabOverlap) - borderThickness; //todo: draw navi wipe behind tabbar - must be drawn with first draw if (skinElement==QS60StylePrivate::SE_TabBarTabEastInactive|| @@ -1543,9 +1559,9 @@ QStyleOptionTabV3 optionTab = *tab; QRect tr = optionTab.rect; const bool directionMirrored = (optionTab.direction == Qt::RightToLeft); - const int borderThickness = QS60StylePrivate::pixelMetric(QStyle::PM_DefaultFrameWidth); + const int borderThickness = QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth); const int tabOverlap = - QS60StylePrivate::pixelMetric(QStyle::PM_TabBarTabOverlap) - borderThickness; + QS60StylePrivate::pixelMetric(PM_TabBarTabOverlap) - borderThickness; const QRect windowRect = painter->window(); switch (tab->shape) { @@ -1571,16 +1587,16 @@ f.setPointSizeF(f.pointSizeF() * KTabFontMul); painter->setFont(f); - if (option->state & QStyle::State_Selected){ + const bool selected = optionTab.state & State_Selected; + if (selected) optionTab.palette.setColor(QPalette::Active, QPalette::WindowText, QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 3, option)); - } const bool verticalTabs = optionTab.shape == QTabBar::RoundedEast || optionTab.shape == QTabBar::RoundedWest || optionTab.shape == QTabBar::TriangularEast || optionTab.shape == QTabBar::TriangularWest; - const bool selected = optionTab.state & State_Selected; + if (verticalTabs) { painter->save(); int newX, newY, newRotation; @@ -1599,12 +1615,12 @@ m.rotate(newRotation); painter->setTransform(m, true); } - tr.adjust(0, 0, pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, tab, widget), - pixelMetric(QStyle::PM_TabBarTabShiftVertical, tab, widget)); + tr.adjust(0, 0, pixelMetric(PM_TabBarTabShiftHorizontal, tab, widget), + pixelMetric(PM_TabBarTabShiftVertical, tab, widget)); if (selected) { - tr.setBottom(tr.bottom() - pixelMetric(QStyle::PM_TabBarTabShiftVertical, tab, widget)); - tr.setRight(tr.right() - pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, tab, widget)); + tr.setBottom(tr.bottom() - pixelMetric(PM_TabBarTabShiftVertical, tab, widget)); + tr.setRight(tr.right() - pixelMetric(PM_TabBarTabShiftHorizontal, tab, widget)); } int alignment = Qt::AlignCenter | Qt::TextShowMnemonic; @@ -1618,12 +1634,12 @@ QPixmap tabIcon = optionTab.icon.pixmap(iconSize, (optionTab.state & State_Enabled) ? QIcon::Normal : QIcon::Disabled); if (tab->text.isEmpty()) - painter->drawPixmap(tr.center().x() - (tabIcon.height() >>1), - tr.center().y() - (tabIcon.height() >>1), + painter->drawPixmap(tr.center().x() - (tabIcon.height() >> 1), + tr.center().y() - (tabIcon.height() >> 1), tabIcon); else painter->drawPixmap(tr.left() + tabOverlap, - tr.center().y() - (tabIcon.height() >>1), + tr.center().y() - (tabIcon.height() >> 1), tabIcon); tr.setLeft(tr.left() + iconSize.width() + 4); } @@ -1645,17 +1661,20 @@ // busy indicator const QS60StylePrivate::SkinElementFlag orientationFlag = optionProgressBar->orientation == Qt::Horizontal ? QS60StylePrivate::SF_PointNorth : QS60StylePrivate::SF_PointWest; - QS60StylePrivate::drawSkinPart(QS60StyleEnums::SP_QgnGrafBarWait, painter, progressRect, flags | orientationFlag); + + QS60StylePrivate::drawSkinPart(QS60StyleEnums::SP_QgnGrafBarWaitAnim, + painter, progressRect, flags | orientationFlag | QS60StylePrivate::SF_Animation ); } else { const qreal progressFactor = (optionProgressBar->minimum == optionProgressBar->maximum) ? 1.0 : (qreal)optionProgressBar->progress / optionProgressBar->maximum; + const int frameWidth = pixelMetric(PM_DefaultFrameWidth, option, widget); if (optionProgressBar->orientation == Qt::Horizontal) { progressRect.setWidth(int(progressRect.width() * progressFactor)); if(optionProgressBar->direction == Qt::RightToLeft) - progressRect.translate(optionProgressBar->rect.width()-progressRect.width(),0); - progressRect.adjust(1, 0, -1, 0); + progressRect.translate(optionProgressBar->rect.width() - progressRect.width(), 0); + progressRect.adjust(frameWidth, 0, -frameWidth, 0); } else { - progressRect.adjust(0, 1, 0, -1); + progressRect.adjust(0, frameWidth, 0, -frameWidth); progressRect.setTop(progressRect.bottom() - int(progressRect.height() * progressFactor)); } @@ -1711,25 +1730,25 @@ QRect textRect = subElementRect(SE_ItemViewItemText, &optionMenuItem, widget); //todo: move the vertical spacing stuff into subElementRect - const int vSpacing = QS60StylePrivate::pixelMetric(QStyle::PM_LayoutVerticalSpacing); + const int vSpacing = QS60StylePrivate::pixelMetric(PM_LayoutVerticalSpacing); if (checkable){ - const int hSpacing = QS60StylePrivate::pixelMetric(QStyle::PM_LayoutHorizontalSpacing); + const int hSpacing = QS60StylePrivate::pixelMetric(PM_LayoutHorizontalSpacing); QStyleOptionMenuItem optionCheckBox; optionCheckBox.QStyleOptionMenuItem::operator=(*menuItem); optionCheckBox.rect.setWidth(pixelMetric(PM_IndicatorWidth)); optionCheckBox.rect.setHeight(pixelMetric(PM_IndicatorHeight)); - const int moveByX = optionCheckBox.rect.width()+vSpacing; + const int moveByX = optionCheckBox.rect.width() + vSpacing; if (optionMenuItem.direction == Qt::LeftToRight) { - textRect.translate(moveByX,0); + textRect.translate(moveByX, 0); iconRect.translate(moveByX, 0); - iconRect.setWidth(iconRect.width()+vSpacing); - textRect.setWidth(textRect.width()-moveByX-vSpacing); - optionCheckBox.rect.translate(vSpacing/2, hSpacing/2); + iconRect.setWidth(iconRect.width() + vSpacing); + textRect.setWidth(textRect.width() - moveByX - vSpacing); + optionCheckBox.rect.translate(vSpacing >> 1, hSpacing >> 1); } else { - textRect.setWidth(textRect.width()-moveByX); - iconRect.setWidth(iconRect.width()+vSpacing); - iconRect.translate(-optionCheckBox.rect.width()-vSpacing, 0); - optionCheckBox.rect.translate(textRect.width()+iconRect.width(),0); + textRect.setWidth(textRect.width() - moveByX); + iconRect.setWidth(iconRect.width() + vSpacing); + iconRect.translate(-optionCheckBox.rect.width() - vSpacing, 0); + optionCheckBox.rect.translate(textRect.width() + iconRect.width(), 0); } drawPrimitive(PE_IndicatorMenuCheckMark, &optionCheckBox, painter, widget); } @@ -1740,9 +1759,9 @@ if (itemWithIcon) { drawItemPixmap(painter, iconRect, text_flags, pix); if (optionMenuItem.direction == Qt::LeftToRight) - textRect.translate(vSpacing,0); + textRect.translate(vSpacing, 0); else - textRect.translate(-vSpacing,0); + textRect.translate(-vSpacing, 0); textRect.setWidth(textRect.width()-vSpacing); } @@ -1750,8 +1769,8 @@ if (drawSubMenuIndicator) { QStyleOptionMenuItem arrowOptions; arrowOptions.QStyleOption::operator=(*menuItem); - const int indicatorWidth = (pixelMetric(PM_ListViewIconSize, option, widget)>>1) + - pixelMetric(QStyle::PM_LayoutVerticalSpacing, option, widget); + const int indicatorWidth = (pixelMetric(PM_ListViewIconSize, option, widget) >> 1) + + pixelMetric(PM_LayoutVerticalSpacing, option, widget); if (optionMenuItem.direction == Qt::LeftToRight) arrowOptions.rect.setLeft(textRect.right()); arrowOptions.rect.setWidth(indicatorWidth); @@ -1795,8 +1814,8 @@ painter->save(); QPen linePen = QPen(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors, 1, header)); const int penWidth = (header->orientation == Qt::Horizontal) ? - linePen.width()+QS60StylePrivate::pixelMetric(PM_Custom_BoldLineWidth) - : linePen.width()+QS60StylePrivate::pixelMetric(PM_Custom_ThinLineWidth); + linePen.width() + QS60StylePrivate::pixelMetric(PM_Custom_BoldLineWidth) + : linePen.width() + QS60StylePrivate::pixelMetric(PM_Custom_ThinLineWidth); linePen.setWidth(penWidth); painter->setPen(linePen); if (header->orientation == Qt::Horizontal){ @@ -1815,7 +1834,7 @@ //Make cornerButton slightly smaller so that it is not on top of table border graphic. QStyleOptionHeader subopt = *header; const int borderTweak = - QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth)>>1; + QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth) >> 1; if (subopt.direction == Qt::LeftToRight) subopt.rect.adjust(borderTweak, borderTweak, 0, -borderTweak); else @@ -1891,7 +1910,7 @@ case CE_ShapedFrame: if (const QTextEdit *textEdit = qobject_cast(widget)) { const QStyleOptionFrame *frame = qstyleoption_cast(option); - if (QS60StylePrivate::canDrawThemeBackground(frame->palette.base())) + if (QS60StylePrivate::canDrawThemeBackground(frame->palette.base(), widget)) QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_Editor, painter, option->rect, flags); else QCommonStyle::drawControl(element, option, painter, widget); @@ -1908,9 +1927,9 @@ } else { const int frameWidth = QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth); if (option->direction == Qt::LeftToRight) - headerRect.adjust(-2*frameWidth, 0, 0, 0); + headerRect.adjust(-2 * frameWidth, 0, 0, 0); else - headerRect.adjust(0, 0, 2*frameWidth, 0); + headerRect.adjust(0, 0, 2 * frameWidth, 0); } if (option->palette.brush(QPalette::Button).color() == Qt::transparent) QS60StylePrivate::drawSkinElement( @@ -1922,8 +1941,7 @@ break; case CE_MenuScroller: break; - case CE_FocusFrame: - { + case CE_FocusFrame: { // The pen width should nearly fill the layoutspacings around the widget const int penWidth = qMin(pixelMetric(QS60Style::PM_LayoutVerticalSpacing), pixelMetric(QS60Style::PM_LayoutHorizontalSpacing)) @@ -1982,11 +2000,21 @@ */ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const { - Q_D(const QS60Style); const QS60StylePrivate::SkinElementFlags flags = (option->state & State_Enabled) ? QS60StylePrivate::SF_StateEnabled : QS60StylePrivate::SF_StateDisabled; bool commonStyleDraws = false; switch (element) { + case PE_FrameFocusRect: { + //Draw themed highlight to radiobuttons and checkboxes. + //For other widgets skip, unless palette has been modified. In that case, draw with commonstyle. + if (option->palette.highlight().color() == QS60StylePrivate::themePalette()->highlight().color()) + if ((qstyleoption_cast(option) && + (qobject_cast(widget) || qobject_cast(widget)))) + QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ListHighlight, painter, option->rect, flags); + else + commonStyleDraws = true; + } + break; #ifndef QT_NO_LINEEDIT case PE_PanelLineEdit: if (const QStyleOptionFrame *lineEdit = qstyleoption_cast(option)) { @@ -1994,22 +2022,21 @@ if (widget && qobject_cast(widget->parentWidget())) break; #endif - if (QS60StylePrivate::canDrawThemeBackground(option->palette.base())) + if (QS60StylePrivate::canDrawThemeBackground(option->palette.base(), widget)) QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_FrameLineEdit, painter, option->rect, flags); else commonStyleDraws = true; } break; #endif // QT_NO_LINEEDIT - case PE_IndicatorCheckBox: - { + case PE_IndicatorCheckBox: { // Draw checkbox indicator as color skinned graphics. - const QS60StyleEnums::SkinParts skinPart = (option->state & QStyle::State_On) ? + const QS60StyleEnums::SkinParts skinPart = (option->state & State_On) ? QS60StyleEnums::SP_QgnIndiCheckboxOn : QS60StyleEnums::SP_QgnIndiCheckboxOff; painter->save(); - QColor themeColor = QS60StylePrivate::themePalette()->windowText().color(); - QColor windowTextColor = option->palette.windowText().color(); + const QColor themeColor = QS60StylePrivate::themePalette()->windowText().color(); + const QColor windowTextColor = option->palette.windowText().color(); if (themeColor != windowTextColor) painter->setPen(windowTextColor); @@ -2029,11 +2056,11 @@ if (checkBoxVisible && singleSelection) { drawPrimitive(PE_IndicatorCheckBox, option, painter, widget); // ... or normal "tick" selection at the end. - } else if (option->state & QStyle::State_Selected) { + } else if (option->state & State_Selected) { QRect tickRect = option->rect; const int frameBorderWidth = QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth); // adjust tickmark rect to exclude frame border - tickRect.adjust(0,-frameBorderWidth,0,-frameBorderWidth); + tickRect.adjust(0, -frameBorderWidth, 0, -frameBorderWidth); QS60StyleEnums::SkinParts skinPart = QS60StyleEnums::SP_QgnIndiMarkedAdd; QS60StylePrivate::drawSkinPart(skinPart, painter, tickRect, (flags | QS60StylePrivate::SF_ColorSkinned)); @@ -2045,7 +2072,7 @@ case PE_IndicatorRadioButton: { QRect buttonRect = option->rect; //there is empty (a. 33%) space in svg graphics for radiobutton - const qreal reduceWidth = (qreal)buttonRect.width()/3.0; + const qreal reduceWidth = (qreal)buttonRect.width() / 3.0; const qreal rectWidth = (qreal)option->rect.width() != 0 ? option->rect.width() : 1.0; // Try to occupy the full area const qreal scaler = 1 + (reduceWidth/rectWidth); @@ -2056,15 +2083,15 @@ buttonRect.adjust(0, -newY, -1, -newY); painter->save(); - QColor themeColor = d->s60Color(QS60StyleEnums::CL_QsnTextColors, 6, option); - QColor buttonTextColor = option->palette.buttonText().color(); + const QColor themeColor = QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 6, option); + const QColor buttonTextColor = option->palette.buttonText().color(); if (themeColor != buttonTextColor) painter->setPen(buttonTextColor); else painter->setPen(themeColor); // Draw radiobutton indicator as color skinned graphics. - QS60StyleEnums::SkinParts skinPart = (option->state & QStyle::State_On) ? + QS60StyleEnums::SkinParts skinPart = (option->state & State_On) ? QS60StyleEnums::SP_QgnIndiRadiobuttOn : QS60StyleEnums::SP_QgnIndiRadiobuttOff; QS60StylePrivate::drawSkinPart(skinPart, painter, buttonRect, (flags | QS60StylePrivate::SF_ColorSkinned)); @@ -2074,15 +2101,14 @@ case PE_PanelButtonCommand: case PE_PanelButtonTool: case PE_PanelButtonBevel: - case PE_FrameButtonBevel: { - if (QS60StylePrivate::canDrawThemeBackground(option->palette.base())) { - const bool isPressed = option->state & QStyle::State_Sunken; + case PE_FrameButtonBevel: + if (QS60StylePrivate::canDrawThemeBackground(option->palette.base(), widget)) { + const bool isPressed = option->state & State_Sunken; const QS60StylePrivate::SkinElements skinElement = isPressed ? QS60StylePrivate::SE_ButtonPressed : QS60StylePrivate::SE_ButtonNormal; QS60StylePrivate::drawSkinElement(skinElement, painter, option->rect, flags); } else { commonStyleDraws = true; - } } break; #ifndef QT_NO_TOOLBUTTON @@ -2108,27 +2134,28 @@ case PE_IndicatorSpinDown: case PE_IndicatorSpinUp: if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast(option)) { - QStyleOptionSpinBox optionSpinBox = *spinBox; - if (QS60StylePrivate::canDrawThemeBackground(optionSpinBox.palette.base())) { + if (QS60StylePrivate::canDrawThemeBackground(spinBox->palette.base(), widget)) { + QStyleOptionSpinBox optionSpinBox = *spinBox; const QS60StyleEnums::SkinParts part = (element == PE_IndicatorSpinUp) ? QS60StyleEnums::SP_QgnGrafScrollArrowUp : QS60StyleEnums::SP_QgnGrafScrollArrowDown; - const int adjustment = qMin(optionSpinBox.rect.width(), optionSpinBox.rect.height())/6; - optionSpinBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? adjustment : -adjustment ); - QS60StylePrivate::drawSkinPart(part, painter, optionSpinBox.rect,flags); + const int iconMargin = QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth) >> 1; + optionSpinBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? iconMargin : -iconMargin ); + QS60StylePrivate::drawSkinPart(part, painter, optionSpinBox.rect, flags); } else { commonStyleDraws = true; } } +#endif //QT_NO_SPINBOX #ifndef QT_NO_COMBOBOX - else if (const QStyleOptionFrame *cmb = qstyleoption_cast(option)) { - if (QS60StylePrivate::canDrawThemeBackground( option->palette.base())) { + if (const QStyleOptionFrame *cmb = qstyleoption_cast(option)) { + if (QS60StylePrivate::canDrawThemeBackground( option->palette.base(), widget)) { // We want to draw down arrow here for comboboxes as well. + QStyleOptionFrame optionsComboBox = *cmb; const QS60StyleEnums::SkinParts part = QS60StyleEnums::SP_QgnGrafScrollArrowDown; - QStyleOptionFrame comboBox = *cmb; - const int adjustment = qMin(comboBox.rect.width(), comboBox.rect.height())/6; - comboBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? adjustment : -adjustment ); - QS60StylePrivate::drawSkinPart(part, painter, comboBox.rect,flags); + const int iconMargin = QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth) >> 1; + optionsComboBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? iconMargin : -iconMargin ); + QS60StylePrivate::drawSkinPart(part, painter, optionsComboBox.rect, flags); } else { commonStyleDraws = true; } @@ -2146,12 +2173,11 @@ // We want to draw down arrow here for comboboxes as well. QStyleOptionFrame comboBox = *cmb; const int frameWidth = QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth); - comboBox.rect.adjust(0,frameWidth,0,-frameWidth); + comboBox.rect.adjust(0, frameWidth, 0, -frameWidth); QCommonStyle::drawPrimitive(element, &comboBox, painter, widget); } #endif //QT_NO_COMBOBOX break; -#endif //QT_NO_SPINBOX case PE_Widget: if (QS60StylePrivate::drawsOwnThemeBackground(widget) #ifndef QT_NO_COMBOBOX @@ -2161,7 +2187,10 @@ || qobject_cast (widget) #endif //QT_NO_MENU ) { - if (QS60StylePrivate::canDrawThemeBackground(option->palette.base())) + //Need extra check since dialogs have their own theme background + if (QS60StylePrivate::canDrawThemeBackground(option->palette.base(), widget) && + option->palette.window().texture().cacheKey() == + QS60StylePrivate::m_themePalette->window().texture().cacheKey()) QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_OptionsMenu, painter, option->rect, flags); else commonStyleDraws = true; @@ -2201,7 +2230,6 @@ break; #ifndef QT_NO_ITEMVIEWS case PE_PanelItemViewItem: - case PE_PanelItemViewRow: // ### Qt 5: remove break; #endif //QT_NO_ITEMVIEWS @@ -2258,22 +2286,45 @@ QS60StyleEnums::SkinParts skinPart = (option->state & State_Open) ? QS60StyleEnums::SP_QgnIndiHlColSuper : QS60StyleEnums::SP_QgnIndiHlExpSuper; int minDimension = qMin(option->rect.width(), option->rect.height()); - const int resizeValue = minDimension >> 1; - minDimension += resizeValue; // Adjust the icon bigger because of empty space in svg icon. QRect iconRect(option->rect.topLeft(), QSize(minDimension, minDimension)); - int verticalMagic(0); - // magic values for positioning svg icon. - if (option->rect.width() <= option->rect.height()) - verticalMagic = 3; - iconRect.translate(3, verticalMagic - resizeValue); + const int magicTweak = 3; + int resizeValue = minDimension >> 1; + if (!QS60StylePrivate::isTouchSupported()) { + minDimension += resizeValue; // Adjust the icon bigger because of empty space in svg icon. + iconRect.setSize(QSize(minDimension, minDimension)); + const int verticalMagic = (option->rect.width() <= option->rect.height()) ? magicTweak : 0; + resizeValue = verticalMagic - resizeValue; + } + iconRect.translate(magicTweak, resizeValue); QS60StylePrivate::drawSkinPart(skinPart, painter, iconRect, flags); } } break; - + case PE_PanelItemViewRow: // ### Qt 5: remove +#ifndef QT_NO_ITEMVIEWS + if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast(option)) { + if (vopt->palette.base().texture().cacheKey() != QS60StylePrivate::m_themePalette->base().texture().cacheKey()) { + //QPalette::Base has been changed, let commonstyle draw the item + commonStyleDraws = true; + } else { + QPalette::ColorGroup cg = vopt->state & State_Enabled ? QPalette::Normal : QPalette::Disabled; + if (cg == QPalette::Normal && !(vopt->state & State_Active)) + cg = QPalette::Inactive; + if (vopt->features & QStyleOptionViewItemV2::Alternate) + painter->fillRect(vopt->rect, vopt->palette.brush(cg, QPalette::AlternateBase)); + //apart from alternate base, no background for list item is drawn for S60Style + } + } +#endif + break; case PE_PanelScrollAreaCorner: break; - + case PE_IndicatorItemViewItemDrop: + if (QS60StylePrivate::isTouchSupported()) + QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_DropArea, painter, option->rect, flags); + else + commonStyleDraws = true; + break; // todo: items are below with #ifdefs "just in case". in final version, remove all non-required cases case PE_FrameLineEdit: case PE_IndicatorDockWidgetResizeHandle: @@ -2294,7 +2345,6 @@ #endif //QT_NO_TOOLBAR #ifndef QT_NO_COLUMNVIEW case PE_IndicatorColumnViewArrow: - case PE_IndicatorItemViewItemDrop: #endif //QT_NO_COLUMNVIEW case PE_FrameTabBarBase: // since tabs are in S60 always in navipane, let's use common style for tab base in Qt. default: @@ -2338,25 +2388,34 @@ case CT_ToolButton: sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget); //FIXME properly - style should calculate the location of border frame-part - sz += QSize(2*pixelMetric(PM_ButtonMargin), 2*pixelMetric(PM_ButtonMargin)); + sz += QSize(2 * pixelMetric(PM_ButtonMargin), 2 * pixelMetric(PM_ButtonMargin)); if (const QStyleOptionToolButton *toolBtn = qstyleoption_cast(opt)) if (toolBtn->subControls & SC_ToolButtonMenu) - sz += QSize(pixelMetric(PM_MenuButtonIndicator),0); + sz += QSize(pixelMetric(PM_MenuButtonIndicator), 0); break; case CT_PushButton: sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget); //FIXME properly - style should calculate the location of border frame-part - sz += QSize(2*pixelMetric(PM_ButtonMargin), 2*pixelMetric(PM_ButtonMargin)); - if (const QAbstractButton *buttonWidget = (qobject_cast(widget))) + if (const QAbstractButton *buttonWidget = (qobject_cast(widget))) { if (buttonWidget->isCheckable()) sz += QSize(pixelMetric(PM_IndicatorWidth) + pixelMetric(PM_CheckBoxLabelSpacing), 0); + const int iconHeight = (!buttonWidget->icon().isNull()) ? buttonWidget->iconSize().height() : 0; + const int textHeight = (buttonWidget->text().length() > 0) ? + buttonWidget->fontMetrics().size(Qt::TextSingleLine, buttonWidget->text()).height() : 0; + const int decoratorHeight = (buttonWidget->isCheckable()) ? pixelMetric(PM_IndicatorHeight) : 0; + + const int contentHeight = + qMax(qMax(iconHeight, decoratorHeight) + pixelMetric(PM_ButtonMargin), + textHeight + 2*pixelMetric(PM_ButtonMargin)); + sz.setHeight(contentHeight); + sz += QSize(2 * pixelMetric(PM_ButtonMargin), 0); + } break; case CT_LineEdit: if (const QStyleOptionFrame *f = qstyleoption_cast(opt)) - sz += QSize(2*f->lineWidth, 4*f->lineWidth); + sz += QSize(2 * f->lineWidth, 4 * f->lineWidth); break; - case CT_TabBarTab: - { + case CT_TabBarTab: { const QSize naviPaneSize = QS60StylePrivate::naviPaneSize(); sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget); if (naviPaneSize.height() > sz.height()) @@ -2368,8 +2427,19 @@ if (QS60StylePrivate::isTouchSupported()) //Make itemview easier to use in touch devices //QCommonStyle does not adjust height with horizontal margin, it only adjusts width - sz.setHeight(sz.height() + 2*pixelMetric(QStyle::PM_FocusFrameVMargin)); + sz.setHeight(sz.height() + 2 * pixelMetric(PM_FocusFrameVMargin)); break; +#ifndef QT_NO_COMBOBOX + case CT_ComboBox: { + // Fixing Ui design issues with too wide QComboBoxes and greedy SizeHints + // Make sure, that the combobox says within the screen. + const QSize desktopContentSize = QApplication::desktop()->availableGeometry().size() + -QSize(pixelMetric(PM_LayoutLeftMargin) + pixelMetric(PM_LayoutRightMargin), 0); + sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget). + boundedTo(desktopContentSize); + } + break; +#endif default: sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget); break; @@ -2384,10 +2454,10 @@ int retValue = -1; switch (sh) { case SH_Table_GridLineColor: - retValue = int(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors,2,0).rgba()); + retValue = int(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors, 2, 0).rgba()); break; case SH_GroupBox_TextLabelColor: - retValue = int(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors,6,0).rgba()); + retValue = int(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 6, 0).rgba()); break; case SH_ScrollBar_ScrollWhenPointerLeavesControl: retValue = true; @@ -2408,7 +2478,7 @@ retValue = QPalette::Base; break; case SH_ItemView_ActivateItemOnSingleClick: - retValue = true; + retValue = QS60StylePrivate::isSingleClickUi(); break; case SH_ProgressDialog_TextLabelAlignment: retValue = (QApplication::layoutDirection() == Qt::LeftToRight) ? @@ -2442,6 +2512,9 @@ case SH_FormLayoutWrapPolicy: retValue = QFormLayout::WrapLongRows; break; + case SH_ScrollBar_ContextMenu: + retValue = false; + break; default: retValue = QCommonStyle::styleHint(sh, opt, widget, hret); break; @@ -2469,7 +2542,7 @@ sliderlen = (qint64(scrollbarOption->pageStep) * maxlen) / (range + scrollbarOption->pageStep); const int slidermin = pixelMetric(PM_ScrollBarSliderMin, scrollbarOption, widget); - if (sliderlen < slidermin || range > (INT_MAX>>1)) + if (sliderlen < slidermin || range > (INT_MAX >> 1)) sliderlen = slidermin; if (sliderlen > maxlen) sliderlen = maxlen; @@ -2520,39 +2593,40 @@ if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast(option)) { const int frameThickness = spinbox->frame ? pixelMetric(PM_SpinBoxFrameWidth, spinbox, widget) : 0; const int buttonMargin = spinbox->frame ? 2 : 0; - const int buttonWidth = QS60StylePrivate::pixelMetric(QStyle::PM_ButtonIconSize) + 2*buttonMargin; + const int buttonContentWidth = QS60StylePrivate::pixelMetric(PM_ButtonIconSize) + 2 * buttonMargin; QSize buttonSize; buttonSize.setHeight(qMax(8, spinbox->rect.height() - frameThickness)); - buttonSize.setWidth(buttonWidth); + //width should at least be equal to height + buttonSize.setWidth(qMax(buttonSize.height(), buttonContentWidth)); buttonSize = buttonSize.expandedTo(QApplication::globalStrut()); const int y = frameThickness + spinbox->rect.y(); - const int x = spinbox->rect.x() + spinbox->rect.width() - frameThickness - 2*buttonSize.width(); + const int x = spinbox->rect.x() + spinbox->rect.width() - frameThickness - 2 * buttonSize.width(); switch (scontrol) { case SC_SpinBoxUp: if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons) return QRect(); - ret = QRect(x, y, buttonWidth, buttonSize.height()); + ret = QRect(x, y, buttonSize.width(), buttonSize.height()); break; case SC_SpinBoxDown: if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons) return QRect(); - ret = QRect(x+buttonSize.width(), y, buttonWidth, buttonSize.height()); + ret = QRect(x + buttonSize.width(), y, buttonSize.width(), buttonSize.height()); break; case SC_SpinBoxEditField: if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons) ret = QRect( frameThickness, frameThickness, - spinbox->rect.width() - 2*frameThickness, - spinbox->rect.height() - 2*frameThickness); + spinbox->rect.width() - 2 * frameThickness, + spinbox->rect.height() - 2 * frameThickness); else ret = QRect( frameThickness, frameThickness, x - frameThickness, - spinbox->rect.height() - 2*frameThickness); + spinbox->rect.height() - 2 * frameThickness); break; case SC_SpinBoxFrame: ret = spinbox->rect; @@ -2568,34 +2642,36 @@ ret = cmb->rect; const int width = cmb->rect.width(); const int height = cmb->rect.height(); + const int buttonIconSize = QS60StylePrivate::pixelMetric(PM_ButtonIconSize); const int buttonMargin = cmb->frame ? 2 : 0; // lets use spinbox frame here as well, as no combobox specific value available. const int frameThickness = cmb->frame ? pixelMetric(PM_SpinBoxFrameWidth, cmb, widget) : 0; - const int buttonWidth = QS60StylePrivate::pixelMetric(QStyle::PM_ButtonIconSize); + const int buttonWidth = qMax(cmb->rect.height(), buttonIconSize); QSize buttonSize; - buttonSize.setHeight(qMax(8, (cmb->rect.height()>>1) - frameThickness)); //minimum of 8 pixels - buttonSize.setWidth(buttonWidth+2*buttonMargin); + buttonSize.setWidth(buttonWidth + 2 * buttonMargin); + buttonSize.setHeight(qMax(8, (cmb->rect.height() >> 1) - frameThickness)); //buttons should be squares buttonSize = buttonSize.expandedTo(QApplication::globalStrut()); switch (scontrol) { - case SC_ComboBoxArrow: - ret.setRect( - ret.x() + ret.width() - buttonMargin - buttonWidth, - ret.y() + buttonMargin, - buttonWidth, - height - 2*buttonMargin); + case SC_ComboBoxArrow: { + const int xposMod = cmb->rect.x() + width - buttonMargin - buttonWidth; + const int ypos = cmb->rect.y(); + ret.setRect(xposMod, ypos + buttonMargin, buttonWidth, height - 2 * buttonMargin); + } break; case SC_ComboBoxEditField: { - ret.setRect( - ret.x() + frameThickness, - ret.y() + frameThickness, - ret.width() - 2*frameThickness - buttonSize.width(), - ret.height() - 2*frameThickness); + const int withFrameX = cmb->rect.x() + width - frameThickness - buttonSize.width(); + ret = QRect( + frameThickness, + frameThickness, + withFrameX - frameThickness, + height - 2 * frameThickness); } break; default: break; } + ret = visualRect(cmb->direction, cmb->rect, ret); } break; case CC_GroupBox: @@ -2606,8 +2682,8 @@ case SC_GroupBoxLabel: { //slightly indent text and boxes, so that dialog border does not mess with them. const int horizontalSpacing = - QS60StylePrivate::pixelMetric(QStyle::PM_LayoutHorizontalSpacing); - ret.adjust(2,horizontalSpacing-3,0,0); + QS60StylePrivate::pixelMetric(PM_LayoutHorizontalSpacing); + ret.adjust(2, horizontalSpacing - 3, 0, 0); } break; case SC_GroupBoxFrame: { @@ -2615,7 +2691,7 @@ const int tbHeight = textBox.height(); ret.translate(0, -ret.y()); // include title to within the groupBox frame - ret.setHeight(ret.height()+tbHeight); + ret.setHeight(ret.height() + tbHeight); if (widget && ret.bottom() > widget->rect().bottom()) ret.setBottom(widget->rect().bottom()); } @@ -2627,7 +2703,7 @@ break; case CC_ToolButton: if (const QStyleOptionToolButton *toolButton = qstyleoption_cast(option)) { - const int indicatorRect = pixelMetric(PM_MenuButtonIndicator) + 2*pixelMetric(PM_ButtonMargin); + const int indicatorRect = pixelMetric(PM_MenuButtonIndicator) + 2 * pixelMetric(PM_ButtonMargin); const int border = pixelMetric(PM_ButtonMargin) + pixelMetric(PM_DefaultFrameWidth); ret = toolButton->rect; const bool popup = (toolButton->features & @@ -2661,17 +2737,20 @@ { QRect ret; switch (element) { + case SE_RadioButtonFocusRect: + ret = opt->rect; + break; case SE_LineEditContents: { // in S60 the input text box doesn't start from line Edit's TL, but // a bit indented. QRect lineEditRect = opt->rect; - const int adjustment = opt->rect.height()>>2; - lineEditRect.adjust(adjustment,0,0,0); + const int adjustment = opt->rect.height() >> 2; + lineEditRect.adjust(adjustment, 0, 0, 0); ret = lineEditRect; } break; case SE_TabBarTearIndicator: - ret = QRect(0,0,0,0); + ret = QRect(0, 0, 0, 0); break; case SE_TabWidgetTabBar: if (const QStyleOptionTabWidgetFrame *optionTab = qstyleoption_cast(opt)) { @@ -2679,9 +2758,9 @@ if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast(opt)) { const int tabOverlapNoBorder = - QS60StylePrivate::pixelMetric(QStyle::PM_TabBarTabOverlap); + QS60StylePrivate::pixelMetric(PM_TabBarTabOverlap); const int tabOverlap = - tabOverlapNoBorder-QS60StylePrivate::pixelMetric(QStyle::PM_DefaultFrameWidth); + tabOverlapNoBorder-QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth); const QTabWidget *tab = qobject_cast(widget); int gain = (tab) ? tabOverlap * tab->count() : 0; switch (twf->shape) { @@ -2693,12 +2772,12 @@ // make sure that gain does not set the rect outside of widget boundaries if (twf->direction == Qt::RightToLeft) { if ((ret.left() - gain) < widget->rect().left()) - gain = widget->rect().left()-ret.left(); - ret.adjust(-gain,0,0,0); + gain = widget->rect().left() - ret.left(); + ret.adjust(-gain, 0, 0, 0); } else { if ((ret.right() + gain) > widget->rect().right()) - gain = widget->rect().right()-ret.right(); - ret.adjust(0,0,gain,0); + gain = widget->rect().right() - ret.right(); + ret.adjust(0, 0, gain, 0); } } break; @@ -2706,8 +2785,8 @@ default: { if (widget) { if ((ret.bottom() + gain) > widget->rect().bottom()) - gain = widget->rect().bottom()-ret.bottom(); - ret.adjust(0,0,0,gain); + gain = widget->rect().bottom() - ret.bottom(); + ret.adjust(0, 0, 0, gain); } break; } @@ -2730,10 +2809,10 @@ multiSelection && (vopt->features & QStyleOptionViewItemV2::HasCheckIndicator)) { const int verticalSpacing = - QS60StylePrivate::pixelMetric(QStyle::PM_LayoutVerticalSpacing); - //const int horizontalSpacing = QS60StylePrivate::pixelMetric(QStyle::PM_LayoutHorizontalSpacing); + QS60StylePrivate::pixelMetric(PM_LayoutVerticalSpacing); + //const int horizontalSpacing = QS60StylePrivate::pixelMetric(PM_LayoutHorizontalSpacing); const int checkBoxRectWidth = subElementRect(SE_ItemViewItemCheckIndicator, opt, widget).width(); - ret.adjust(-checkBoxRectWidth-verticalSpacing,0,-checkBoxRectWidth-verticalSpacing,0); + ret.adjust(-checkBoxRectWidth - verticalSpacing, 0, -checkBoxRectWidth - verticalSpacing, 0); } } else if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast(opt)) { const bool checkable = menuItem->checkType != QStyleOptionMenuItem::NotCheckable; @@ -2758,9 +2837,9 @@ if (menuItem->menuItemType == QStyleOptionMenuItem::SubMenu){ // submenu indicator is very small, so lets halve the rect if (menuItem->direction == Qt::LeftToRight) - ret.adjust(0,0,-(indicatorWidth >> 1),0); + ret.adjust(0, 0, -(indicatorWidth >> 1), 0); else - ret.adjust((indicatorWidth >> 1),0,0,0); + ret.adjust((indicatorWidth >> 1), 0, 0, 0); } } } @@ -2777,21 +2856,21 @@ singleSelection; // Selection check mark rect. - const int indicatorWidth = QS60StylePrivate::pixelMetric(QStyle::PM_IndicatorWidth); - const int indicatorHeight = QS60StylePrivate::pixelMetric(QStyle::PM_IndicatorHeight); - const int spacing = QS60StylePrivate::pixelMetric(QStyle::PM_CheckBoxLabelSpacing); + const int indicatorWidth = QS60StylePrivate::pixelMetric(PM_IndicatorWidth); + const int indicatorHeight = QS60StylePrivate::pixelMetric(PM_IndicatorHeight); + const int spacing = QS60StylePrivate::pixelMetric(PM_CheckBoxLabelSpacing); const int itemHeight = opt->rect.height(); int heightOffset = 0; if (indicatorHeight < itemHeight) - heightOffset = ((itemHeight - indicatorHeight)>>1); + heightOffset = ((itemHeight - indicatorHeight) >> 1); if (checkBoxOnly) { // Move rect and make it slightly smaller, so that // a) highlight border does not cross the rect // b) in s60 list checkbox is smaller than normal checkbox //todo; magic three - ret.setRect(opt->rect.left()+3, opt->rect.top() + heightOffset, - indicatorWidth-3, indicatorHeight-3); + ret.setRect(opt->rect.left() + 3, opt->rect.top() + heightOffset, + indicatorWidth - 3, indicatorHeight - 3); } else { ret.setRect(opt->rect.right() - indicatorWidth - spacing, opt->rect.top() + heightOffset, indicatorWidth, indicatorHeight); @@ -2811,6 +2890,25 @@ } ret = visualRect(opt->direction, opt->rect, ret); break; + case SE_RadioButtonIndicator: { + const int height = pixelMetric(PM_ExclusiveIndicatorHeight, opt, widget); + ret.setRect(opt->rect.x(), opt->rect.y() + ((opt->rect.height() - height) >> 1), + pixelMetric(PM_ExclusiveIndicatorWidth, opt, widget), height); + ret.translate(2, 0); //move indicator slightly to avoid highlight crossing over it + ret = visualRect(opt->direction, opt->rect, ret); + } + break; + case SE_CheckBoxIndicator: { + const int height = pixelMetric(PM_IndicatorHeight, opt, widget); + ret.setRect(opt->rect.x(), opt->rect.y() + ((opt->rect.height() - height) >> 1), + pixelMetric(PM_IndicatorWidth, opt, widget), height); + ret.translate(2, 0); //move indicator slightly to avoid highlight crossing over it + ret = visualRect(opt->direction, opt->rect, ret); + } + break; + case SE_CheckBoxFocusRect: + ret = opt->rect; + break; default: ret = QCommonStyle::subElementRect(element, opt, widget); } @@ -2828,6 +2926,12 @@ if (!widget) return; + //Currently we only support animations in QProgressBar. +#ifndef QT_NO_PROGRESSBAR + if (qobject_cast(widget)) + widget->installEventFilter(this); +#endif + if (false #ifndef QT_NO_SCROLLBAR || qobject_cast(widget) @@ -2860,6 +2964,8 @@ */ void QS60Style::unpolish(QWidget *widget) { + Q_D(QS60Style); + if (false #ifndef QT_NO_SCROLLBAR || qobject_cast(widget) @@ -2886,6 +2992,14 @@ if (widget) widget->setPalette(QPalette()); +#if defined(Q_WS_S60) && !defined(QT_NO_PROGRESSBAR) + if (QProgressBar *bar = qobject_cast(widget)) { + widget->removeEventFilter(this); + d->m_bars.removeAll(bar); + } +#else + Q_UNUSED(d) +#endif QCommonStyle::unpolish(widget); } @@ -2917,10 +3031,23 @@ bool QS60Style::event(QEvent *e) { #ifdef QT_KEYPAD_NAVIGATION - if (QS60StylePrivate::isTouchSupported()) - return false; Q_D(QS60Style); + const QEvent::Type eventType = e->type(); + if ((eventType == QEvent::FocusIn || + eventType == QEvent::FocusOut || + eventType == QEvent::EnterEditFocus || + eventType == QEvent::LeaveEditFocus) && + QS60StylePrivate::isTouchSupported()) + return false; +#endif + switch (e->type()) { + case QEvent::Timer: { + QTimerEvent *te = static_cast(e); + timerEvent(te); + } + break; +#ifdef QT_KEYPAD_NAVIGATION case QEvent::FocusIn: if (QWidget *focusWidget = QApplication::focusWidget()) { if (!d->m_focusFrame) @@ -2939,12 +3066,10 @@ if (d->m_focusFrame) d->m_focusFrame->update(); break; +#endif default: break; } -#else - Q_UNUSED(e) -#endif return false; } @@ -2954,8 +3079,8 @@ QIcon QS60Style::standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget) const { - const int iconDimension = QS60StylePrivate::pixelMetric(QStyle::PM_ToolBarIconSize); - const QRect iconSize = (!option) ? QRect(0,0,iconDimension,iconDimension) : option->rect; + const int iconDimension = QS60StylePrivate::pixelMetric(PM_ToolBarIconSize); + const QRect iconSize = (!option) ? QRect(0, 0, iconDimension, iconDimension) : option->rect; QS60StyleEnums::SkinParts part; QS60StylePrivate::SkinElementFlags adjustedFlags; if (option) @@ -2964,67 +3089,67 @@ QS60StylePrivate::SF_StateDisabled; switch(standardIcon) { - case QStyle::SP_MessageBoxWarning: + case SP_MessageBoxWarning: part = QS60StyleEnums::SP_QgnNoteWarning; break; - case QStyle::SP_MessageBoxInformation: + case SP_MessageBoxInformation: part = QS60StyleEnums::SP_QgnNoteInfo; break; - case QStyle::SP_MessageBoxCritical: + case SP_MessageBoxCritical: part = QS60StyleEnums::SP_QgnNoteError; break; - case QStyle::SP_MessageBoxQuestion: + case SP_MessageBoxQuestion: part = QS60StyleEnums::SP_QgnNoteQuery; break; - case QStyle::SP_ArrowRight: + case SP_ArrowRight: part = QS60StyleEnums::SP_QgnIndiNaviArrowRight; break; - case QStyle::SP_ArrowLeft: + case SP_ArrowLeft: part = QS60StyleEnums::SP_QgnIndiNaviArrowLeft; break; - case QStyle::SP_ArrowUp: + case SP_ArrowUp: part = QS60StyleEnums::SP_QgnIndiNaviArrowLeft; adjustedFlags |= QS60StylePrivate::SF_PointEast; break; - case QStyle::SP_ArrowDown: + case SP_ArrowDown: part = QS60StyleEnums::SP_QgnIndiNaviArrowLeft; adjustedFlags |= QS60StylePrivate::SF_PointWest; break; - case QStyle::SP_ArrowBack: + case SP_ArrowBack: if (QApplication::layoutDirection() == Qt::RightToLeft) return QS60Style::standardIcon(SP_ArrowRight, option, widget); return QS60Style::standardIcon(SP_ArrowLeft, option, widget); - case QStyle::SP_ArrowForward: + case SP_ArrowForward: if (QApplication::layoutDirection() == Qt::RightToLeft) return QS60Style::standardIcon(SP_ArrowLeft, option, widget); return QS60Style::standardIcon(SP_ArrowRight, option, widget); - case QStyle::SP_ComputerIcon: + case SP_ComputerIcon: part = QS60StyleEnums::SP_QgnPropPhoneMemcLarge; break; - case QStyle::SP_DirClosedIcon: + case SP_DirClosedIcon: part = QS60StyleEnums::SP_QgnPropFolderSmall; break; - case QStyle::SP_DirOpenIcon: + case SP_DirOpenIcon: part = QS60StyleEnums::SP_QgnPropFolderCurrent; break; - case QStyle::SP_DirIcon: + case SP_DirIcon: part = QS60StyleEnums::SP_QgnPropFolderSmall; break; - case QStyle::SP_FileDialogNewFolder: + case SP_FileDialogNewFolder: part = QS60StyleEnums::SP_QgnPropFolderSmallNew; break; - case QStyle::SP_FileIcon: + case SP_FileIcon: part = QS60StyleEnums::SP_QgnPropFileSmall; break; - case QStyle::SP_TrashIcon: + case SP_TrashIcon: part = QS60StyleEnums::SP_QgnNoteErased; break; - case QStyle::SP_ToolBarHorizontalExtensionButton: + case SP_ToolBarHorizontalExtensionButton: part = QS60StyleEnums::SP_QgnIndiSubMenu; if (QApplication::layoutDirection() == Qt::RightToLeft) adjustedFlags |= QS60StylePrivate::SF_PointSouth; break; - case QStyle::SP_ToolBarVerticalExtensionButton: + case SP_ToolBarVerticalExtensionButton: adjustedFlags |= QS60StylePrivate::SF_PointEast; part = QS60StyleEnums::SP_QgnIndiSubMenu; break; @@ -3038,6 +3163,72 @@ QCommonStyle::standardIconImplementation(standardIcon, option, widget) : QIcon(cachedPixMap); } +/*! + \internal + Animate indeterminate progress bars only when visible +*/ +bool QS60Style::eventFilter(QObject *object, QEvent *event) +{ +#ifdef Q_WS_S60 +#ifndef QT_NO_PROGRESSBAR + Q_D(QS60Style); + switch(event->type()) { + case QEvent::StyleChange: + case QEvent::Show: + if (QProgressBar *bar = qobject_cast(object)) { + if (!d->m_bars.contains(bar)) + d->m_bars << bar; + if (d->m_bars.size() == 1) //only start with first animated progressbar + d->startAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim); + } + break; + case QEvent::Destroy: + case QEvent::Hide: + d->stopAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim); + d->m_bars.removeAll(reinterpret_cast(object)); + break; + default: + break; + } +#endif // QT_NO_PROGRESSBAR +#endif // Q_WS_S60 + return QStyle::eventFilter(object, event); +} + +/*! + \internal + Handle the timer \a event. +*/ +void QS60Style::timerEvent(QTimerEvent *event) +{ +#ifdef Q_WS_S60 +#ifndef QT_NO_PROGRESSBAR + Q_D(QS60Style); + + QS60StyleAnimation *progressBarAnimation = + QS60StylePrivate::animationDefinition(QS60StyleEnums::SP_QgnGrafBarWaitAnim); + + if (event->timerId() == progressBarAnimation->timerId()) { + + Q_ASSERT(progressBarAnimation->interval() > 0); + + if (progressBarAnimation->currentFrame() == progressBarAnimation->frameCount() ) + if (progressBarAnimation->playMode() == QS60StyleEnums::AM_Looping) + progressBarAnimation->setCurrentFrame(0); + else + d->stopAnimation(progressBarAnimation->animationId()); + + foreach (QProgressBar *bar, d->m_bars) { + if ((bar->minimum() == 0 && bar->maximum() == 0)) + bar->update(); + } + progressBarAnimation->setCurrentFrame(progressBarAnimation->currentFrame() + 1); + } +#endif // QT_NO_PROGRESSBAR +#endif // Q_WS_S60 + event->ignore(); +} + extern QPoint qt_s60_fill_background_offset(const QWidget *targetWidget); bool qt_s60_fill_background(QPainter *painter, const QRegion &rgn, const QBrush &brush) @@ -3049,11 +3240,13 @@ const QPaintDevice *target = painter->device(); if (target->devType() == QInternal::Widget) { const QWidget *widget = static_cast(target); - const QVector &rects = rgn.rects(); - for (int i = 0; i < rects.size(); ++i) { - const QRect rect(rects.at(i)); - painter->drawPixmap(rect.topLeft(), backgroundTexture, - rect.translated(qt_s60_fill_background_offset(widget))); + if (!widget->testAttribute(Qt::WA_TranslucentBackground)) { + const QVector &rects = rgn.rects(); + for (int i = 0; i < rects.size(); ++i) { + const QRect rect(rects.at(i)); + painter->drawPixmap(rect.topLeft(), backgroundTexture, + rect.translated(qt_s60_fill_background_offset(widget))); + } } } return true;