diff -r dee5afe5301f -r 3f74d0d4af4c src/gui/styles/qs60style.cpp --- a/src/gui/styles/qs60style.cpp Mon Mar 15 12:43:09 2010 +0200 +++ b/src/gui/styles/qs60style.cpp Thu Apr 08 14:19:33 2010 +0300 @@ -50,6 +50,7 @@ #include "qcalendarwidget.h" #include "qdial.h" #include "qdialog.h" +#include "qmessagebox.h" #include "qgroupbox.h" #include "qheaderview.h" #include "qlist.h" @@ -61,7 +62,6 @@ #include "qscrollarea.h" #include "qscrollbar.h" #include "qtabbar.h" -#include "qtablewidget.h" #include "qtableview.h" #include "qtextedit.h" #include "qtoolbar.h" @@ -92,10 +92,10 @@ const layoutHeader QS60StylePrivate::m_layoutHeaders[] = { // *** generated layout data *** -{240,320,1,16,"QVGA Landscape"}, -{320,240,1,16,"QVGA Portrait"}, -{360,640,1,16,"NHD Landscape"}, -{640,360,1,16,"NHD Portrait"}, +{240,320,1,17,"QVGA Landscape"}, +{320,240,1,17,"QVGA Portrait"}, +{360,640,1,17,"NHD Landscape"}, +{640,360,1,17,"NHD Portrait"}, {352,800,1,12,"E90 Landscape"} // *** End of generated data *** }; @@ -104,11 +104,11 @@ 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,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} +{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,0,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, 106}, +{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,0,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, 106}, +{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,0,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, 135}, +{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,0,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, 135}, +{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,0,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, 106} // *** End of generated data *** }; @@ -120,12 +120,14 @@ // 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}, {SE_FrameLineEdit, QS60StyleEnums::SP_QsnFrInputCenter}, {SE_ListHighlight, QS60StyleEnums::SP_QsnFrListCenter}, - {SE_OptionsMenu, QS60StyleEnums::SP_QsnFrPopupCenter}, + {SE_PopupBackground, QS60StyleEnums::SP_QsnFrPopupCenter}, {SE_SettingsList, QS60StyleEnums::SP_QsnFrSetOptCenter}, {SE_TableItem, QS60StyleEnums::SP_QsnFrCaleCenter}, {SE_TableHeaderItem, QS60StyleEnums::SP_QsnFrCaleHeadingCenter}, @@ -248,8 +250,8 @@ case SE_ListHighlight: drawFrame(SF_ListHighlight, painter, rect, flags | SF_PointNorth); break; - case SE_OptionsMenu: - drawFrame(SF_OptionsMenu, painter, rect, flags | SF_PointNorth); + case SE_PopupBackground: + drawFrame(SF_PopupBackground, painter, rect, flags | SF_PointNorth); break; case SE_SettingsList: drawFrame(SF_SettingsList, painter, rect, flags | SF_PointNorth); @@ -289,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; } @@ -302,6 +307,13 @@ short QS60StylePrivate::pixelMetric(int metric) { + //If it is a custom value, need to strip away the base to map to internal + //pixel metric value table + if (metric & QStyle::PM_CustomBase) { + metric -= QStyle::PM_CustomBase; + metric += MAX_NON_CUSTOM_PIXELMETRICS - 1; + } + Q_ASSERT(metric < MAX_PIXELMETRICS); const short returnValue = m_pmPointer[metric]; return returnValue; @@ -402,8 +414,8 @@ { const bool cachedColorExists = m_colorCache.contains(frame); if (!cachedColorExists) { - const int frameCornerWidth = pixelMetric(PM_Custom_FrameCornerWidth); - const int frameCornerHeight = pixelMetric(PM_Custom_FrameCornerHeight); + const int frameCornerWidth = pixelMetric(PM_FrameCornerWidth); + const int frameCornerHeight = pixelMetric(PM_FrameCornerHeight); Q_ASSERT(2 * frameCornerWidth < 32); Q_ASSERT(2 * frameCornerHeight < 32); @@ -625,6 +637,8 @@ fontCategory = QS60StyleEnums::FC_Secondary; } else if (qobject_cast(widget)){ fontCategory = QS60StyleEnums::FC_Title; + } else if (qobject_cast(widget)){ + fontCategory = QS60StyleEnums::FC_Primary; } if (fontCategory != QS60StyleEnums::FC_Undefined) { const bool resolveFontSize = widget->testAttribute(Qt::WA_SetFont) @@ -754,13 +768,29 @@ QApplication::setPalette(widgetPalette, "QMenuBar"); widgetPalette = *palette; + widgetPalette.setColor(QPalette::Text, + s60Color(QS60StyleEnums::CL_QsnTextColors, 22, 0)); + widgetPalette.setColor(QPalette::HighlightedText, + s60Color(QS60StyleEnums::CL_QsnTextColors, 11, 0)); + QApplication::setPalette(widgetPalette, "QMenu"); + widgetPalette = *palette; + widgetPalette.setColor(QPalette::WindowText, s60Color(QS60StyleEnums::CL_QsnTextColors, 4, 0)); + widgetPalette.setColor(QPalette::HighlightedText, + s60Color(QS60StyleEnums::CL_QsnTextColors, 3, 0)); QApplication::setPalette(widgetPalette, "QTabBar"); widgetPalette = *palette; + widgetPalette.setColor(QPalette::HighlightedText, + s60Color(QS60StyleEnums::CL_QsnTextColors, 10, 0)); + QApplication::setPalette(widgetPalette, "QListView"); + widgetPalette = *palette; + widgetPalette.setColor(QPalette::Text, s60Color(QS60StyleEnums::CL_QsnTextColors, 22, 0)); + widgetPalette.setColor(QPalette::HighlightedText, + s60Color(QS60StyleEnums::CL_QsnTextColors, 11, 0)); QApplication::setPalette(widgetPalette, "QTableView"); widgetPalette = *palette; @@ -784,6 +814,8 @@ widgetPalette = *palette; widgetPalette.setColor(QPalette::WindowText, s60Color(QS60StyleEnums::CL_QsnTextColors, 7, 0)); + widgetPalette.setColor(QPalette::HighlightedText, + s60Color(QS60StyleEnums::CL_QsnTextColors, 11, 0)); QApplication::setPalette(widgetPalette, "QRadioButton"); QApplication::setPalette(widgetPalette, "QCheckBox"); widgetPalette = *palette; @@ -804,8 +836,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) @@ -841,18 +877,21 @@ case QS60StyleEnums::SP_QgnGrafBarFrameSideL: case QS60StyleEnums::SP_QgnGrafBarFrameSideR: - result.setWidth(pixelMetric(PM_Custom_FrameCornerWidth)); + result.setWidth(pixelMetric(PM_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; @@ -865,15 +904,15 @@ case 7: /* CornerTr */ case 6: /* CornerBl */ case 5: /* CornerBr */ - result.setWidth(pixelMetric(PM_Custom_FrameCornerWidth)); + result.setWidth(pixelMetric(PM_FrameCornerWidth)); // Falltrough intended... case 4: /* SideT */ case 3: /* SideB */ - result.setHeight(pixelMetric(PM_Custom_FrameCornerHeight)); + result.setHeight(pixelMetric(PM_FrameCornerHeight)); break; case 2: /* SideL */ case 1: /* SideR */ - result.setWidth(pixelMetric(PM_Custom_FrameCornerWidth)); + result.setWidth(pixelMetric(PM_FrameCornerWidth)); break; case 0: /* center */ default: @@ -890,8 +929,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; @@ -969,7 +1011,6 @@ QS60StylePrivate::SE_SliderGrooveVertical; QS60StylePrivate::drawSkinElement(grooveElement, painter, sliderGroove, flags); } else { - const QRect sliderGroove = subControlRect(control, optionSlider, SC_SliderGroove, widget); const QPoint sliderGrooveCenter = sliderGroove.center(); const bool horizontal = optionSlider->orientation == Qt::Horizontal; painter->save(); @@ -1096,7 +1137,7 @@ drawPrimitive(pe, &toolButton, painter, widget); } - if (toolBtn->text.length()>0 || + if (toolBtn->text.length() > 0 || !toolBtn->icon.isNull()) { const int frameWidth = pixelMetric(PM_DefaultFrameWidth, option, widget); toolButton.rect = button.adjusted(frameWidth, frameWidth, -frameWidth, -frameWidth); @@ -1226,6 +1267,8 @@ case CE_RadioButton: if (const QStyleOptionButton *btn = qstyleoption_cast(option)) { bool isRadio = (element == CE_RadioButton); + QStyleOptionButton subopt = *btn; + // Highlight needs to be drawn first, as it goes "underneath" the text and indicator. if (btn->state & State_HasFocus) { QStyleOptionFocusRect fropt; @@ -1233,8 +1276,10 @@ fropt.rect = subElementRect(isRadio ? SE_RadioButtonFocusRect : SE_CheckBoxFocusRect, btn, widget); drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget); + + subopt.palette.setColor(QPalette::Active, QPalette::WindowText, + subopt.palette.highlightedText().color()); } - QStyleOptionButton subopt = *btn; subopt.rect = subElementRect(isRadio ? SE_RadioButtonIndicator : SE_CheckBoxIndicator, btn, widget); @@ -1334,7 +1379,7 @@ } if (!comboBox->currentText.isEmpty() && !comboBox->editable) { QCommonStyle::drawItemText(painter, - editRect.adjusted(QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth), 0, -1, 0), + editRect.adjusted(QS60StylePrivate::pixelMetric(PM_FrameCornerWidth), 0, -1, 0), visualAlignment(comboBox->direction, Qt::AlignLeft | Qt::AlignVCenter), comboBox->palette, comboBox->state & State_Enabled, comboBox->currentText); } @@ -1393,7 +1438,7 @@ } else { QCommonStyle::drawPrimitive(PE_PanelItemViewItem, &voptAdj, painter, widget);} // draw the focus rect - if (isSelected | hasFocus) { + if (isSelected || hasFocus ) { QRect highlightRect = option->rect.adjusted(1,1,-1,-1); QAbstractItemView::SelectionBehavior selectionBehavior = itemView ? itemView->selectionBehavior() : QAbstractItemView::SelectItems; @@ -1465,15 +1510,10 @@ // draw the text if (!voptAdj.text.isEmpty()) { - if (isSelected) { - if (qobject_cast(widget)) - voptAdj.palette.setColor( - QPalette::Text, QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 11, 0)); - else - voptAdj.palette.setColor( - QPalette::Text, QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 10, 0)); - } - painter->setPen(voptAdj.palette.text().color()); + if (isSelected || hasFocus ) + painter->setPen(voptAdj.palette.highlightedText().color()); + else + painter->setPen(voptAdj.palette.text().color()); d->viewItemDrawText(painter, &voptAdj, textRect); } painter->restore(); @@ -1575,7 +1615,7 @@ const bool selected = optionTab.state & State_Selected; if (selected) optionTab.palette.setColor(QPalette::Active, QPalette::WindowText, - QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 3, option)); + optionTab.palette.highlightedText().color()); const bool verticalTabs = optionTab.shape == QTabBar::RoundedEast || optionTab.shape == QTabBar::RoundedWest @@ -1708,7 +1748,8 @@ if (!styleHint(SH_UnderlineShortcut, menuItem, widget)) text_flags |= Qt::TextHideMnemonic; - if ((option->state & State_Selected) && (option->state & State_Enabled)) + const bool selected = (option->state & State_Selected) && (option->state & State_Enabled); + if (selected) QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ListHighlight, painter, option->rect, flags); QRect iconRect = subElementRect(SE_ItemViewItemDecoration, &optionMenuItem, widget); @@ -1778,6 +1819,10 @@ painter->save(); painter->setOpacity(0.5); } + if (selected) + optionMenuItem.palette.setColor( + QPalette::Active, QPalette::Text, optionMenuItem.palette.highlightedText().color()); + QCommonStyle::drawItemText(painter, textRect, text_flags, optionMenuItem.palette, enabled, optionMenuItem.text, QPalette::Text); @@ -1799,8 +1844,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_BoldLineWidth) + : linePen.width() + QS60StylePrivate::pixelMetric(PM_ThinLineWidth); linePen.setWidth(penWidth); painter->setPen(linePen); if (header->orientation == Qt::Horizontal){ @@ -1819,7 +1864,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_FrameCornerWidth) >> 1; if (subopt.direction == Qt::LeftToRight) subopt.rect.adjust(borderTweak, borderTweak, 0, -borderTweak); else @@ -1895,7 +1940,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); @@ -1927,40 +1972,37 @@ case CE_MenuScroller: break; 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)) - - 2; // But keep 1 pixel distance to the focus widget and 1 pixel to the adjacent widgets - #ifdef QT_KEYPAD_NAVIGATION bool editFocus = false; if (const QFocusFrame *focusFrame = qobject_cast(widget)) { if (focusFrame->widget() && focusFrame->widget()->hasEditFocus()) editFocus = true; } - const qreal opacity = editFocus ? 0.65 : 0.45; // Trial and error factors. Feel free to improve. + const qreal opacity = editFocus ? 1 : 0.75; // Trial and error factors. Feel free to improve. #else - const qreal opacity = 0.5; + const qreal opacity = 0.85; #endif - // Because of Qts coordinate system, we need to tweak the rect by .5 pixels, otherwise it gets blurred. - const qreal rectAdjustment = (penWidth % 2) ? -.5 : 0; - - // Make sure that the pen stroke is inside the rect - const QRectF adjustedRect = - QRectF(option->rect).adjusted( - rectAdjustment + penWidth, - rectAdjustment + penWidth, - -rectAdjustment - penWidth, - -rectAdjustment - penWidth - ); - - const qreal roundRectRadius = penWidth * goldenRatio; + // We need to reduce the focus frame size if LayoutSpacing is smaller than FocusFrameMargin + // Otherwise, we would overlay adjacent widgets. + const int frameHeightReduction = + qMin(0, pixelMetric(QStyle::PM_LayoutVerticalSpacing) + - pixelMetric(QStyle::PM_FocusFrameVMargin)); + const int frameWidthReduction = + qMin(0, pixelMetric(QStyle::PM_LayoutHorizontalSpacing) + - pixelMetric(QStyle::PM_FocusFrameHMargin)); + const int rounding = + qMin(pixelMetric(QStyle::PM_FocusFrameVMargin), + pixelMetric(QStyle::PM_LayoutVerticalSpacing)); + const QRect frameRect = + option->rect.adjusted(-frameWidthReduction, -frameHeightReduction, + frameWidthReduction, frameHeightReduction); + QPainterPath framePath; + framePath.addRoundedRect(frameRect, rounding, rounding); painter->save(); painter->setRenderHint(QPainter::Antialiasing); painter->setOpacity(opacity); - painter->setPen(QPen(option->palette.color(QPalette::Text), penWidth)); - painter->drawRoundedRect(adjustedRect, roundRectRadius, roundRectRadius); + painter->fillPath(framePath, option->palette.color(QPalette::Text)); painter->restore(); } break; @@ -2007,7 +2049,7 @@ 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; @@ -2032,18 +2074,18 @@ break; case PE_IndicatorViewItemCheck: #ifndef QT_NO_ITEMVIEWS - if (const QListView *listItem = (qobject_cast(widget))) { + if (const QAbstractItemView *itemView = (qobject_cast(widget))) { if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast(option)) { const bool checkBoxVisible = vopt->features & QStyleOptionViewItemV2::HasCheckIndicator; - const bool singleSelection = listItem->selectionMode() == - QAbstractItemView::SingleSelection || listItem->selectionMode() == QAbstractItemView::NoSelection; + const bool singleSelection = itemView->selectionMode() == + QAbstractItemView::SingleSelection || itemView->selectionMode() == QAbstractItemView::NoSelection; // draw either checkbox at the beginning if (checkBoxVisible && singleSelection) { drawPrimitive(PE_IndicatorCheckBox, option, painter, widget); // ... or normal "tick" selection at the end. } else if (option->state & State_Selected) { QRect tickRect = option->rect; - const int frameBorderWidth = QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth); + const int frameBorderWidth = QS60StylePrivate::pixelMetric(PM_FrameCornerWidth); // adjust tickmark rect to exclude frame border tickRect.adjust(0, -frameBorderWidth, 0, -frameBorderWidth); QS60StyleEnums::SkinParts skinPart = QS60StyleEnums::SP_QgnIndiMarkedAdd; @@ -2087,7 +2129,7 @@ case PE_PanelButtonTool: case PE_PanelButtonBevel: case PE_FrameButtonBevel: - if (QS60StylePrivate::canDrawThemeBackground(option->palette.base())) { + 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; @@ -2119,12 +2161,12 @@ case PE_IndicatorSpinDown: case PE_IndicatorSpinUp: if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast(option)) { - if (QS60StylePrivate::canDrawThemeBackground(spinBox->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 iconMargin = QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth) >> 1; + const int iconMargin = QS60StylePrivate::pixelMetric(PM_FrameCornerWidth) >> 1; optionSpinBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? iconMargin : -iconMargin ); QS60StylePrivate::drawSkinPart(part, painter, optionSpinBox.rect, flags); } else { @@ -2134,11 +2176,11 @@ #endif //QT_NO_SPINBOX #ifndef QT_NO_COMBOBOX if (const QStyleOptionFrame *cmb = qstyleoption_cast(option)) { - if (QS60StylePrivate::canDrawThemeBackground( option->palette.base())) { + 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; - const int iconMargin = QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth) >> 1; + const int iconMargin = QS60StylePrivate::pixelMetric(PM_FrameCornerWidth) >> 1; optionsComboBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? iconMargin : -iconMargin ); QS60StylePrivate::drawSkinPart(part, painter, optionsComboBox.rect, flags); } else { @@ -2173,10 +2215,10 @@ #endif //QT_NO_MENU ) { //Need extra check since dialogs have their own theme background - if (QS60StylePrivate::canDrawThemeBackground(option->palette.base()) && + 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); + QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_PopupBackground, painter, option->rect, flags); else commonStyleDraws = true; } @@ -2271,14 +2313,16 @@ 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); } } @@ -2302,7 +2346,12 @@ 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: @@ -2323,7 +2372,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: @@ -2341,13 +2389,6 @@ if (metricValue == KNotFound) metricValue = QCommonStyle::pixelMetric(metric, option, widget); - if (metric == PM_SubMenuOverlap && widget) { - const QMenu *menu = qobject_cast(widget); - if (menu && menu->activeAction() && menu->activeAction()->menu()) { - const int menuWidth = menu->activeAction()->menu()->sizeHint().width(); - metricValue = -menuWidth; - } - } //if layout direction is mirrored, switch left and right border margins if (option && option->direction == Qt::RightToLeft) { if (metric == PM_LayoutLeftMargin) @@ -2355,6 +2396,12 @@ else if (metric == PM_LayoutRightMargin) metricValue = QS60StylePrivate::pixelMetric(PM_LayoutLeftMargin); } + + if (widget && (metric == PM_LayoutTopMargin)) + if (widget->windowType() == Qt::Dialog) + //double the top layout margin for dialogs, it is very close to real value + //without having to define custom pixel metric + metricValue *= 2; return metricValue; } @@ -2375,10 +2422,20 @@ 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)) @@ -2401,9 +2458,9 @@ #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. + // Make sure, that the combobox stays within the screen. const QSize desktopContentSize = QApplication::desktop()->availableGeometry().size() - -QSize(pixelMetric(PM_LayoutLeftMargin) + pixelMetric(PM_LayoutRightMargin), 0); + - QSize(pixelMetric(PM_LayoutLeftMargin) + pixelMetric(PM_LayoutRightMargin), 0); sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget). boundedTo(desktopContentSize); } @@ -2422,6 +2479,15 @@ { int retValue = -1; switch (sh) { + case SH_RequestSoftwareInputPanel: + if (QS60StylePrivate::isSingleClickUi()) + retValue = RSIP_OnMouseClick; + else + retValue = RSIP_OnMouseClickAndAlreadyFocused; + break; + case SH_ComboBox_Popup: + retValue = true; + break; case SH_Table_GridLineColor: retValue = int(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors, 2, 0).rgba()); break; @@ -2475,12 +2541,12 @@ case SH_UnderlineShortcut: retValue = 0; break; - case SH_RequestSoftwareInputPanel: - retValue = RSIP_OnMouseClickAndAlreadyFocused; - break; case SH_FormLayoutWrapPolicy: retValue = QFormLayout::WrapLongRows; break; + case SH_ScrollBar_ContextMenu: + retValue = false; + break; default: retValue = QCommonStyle::styleHint(sh, opt, widget, hret); break; @@ -2559,15 +2625,23 @@ 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(PM_ButtonIconSize) + 2 * buttonMargin; + const int buttonContentWidth = QS60StylePrivate::pixelMetric(PM_ButtonIconSize) + 2 * buttonMargin; + // Spinbox buttons should be no larger than one fourth of total width. + // Thus, side-by-side buttons would take half of the total width. + const int maxSize = qMax(spinbox->rect.width() / 4, buttonContentWidth); QSize buttonSize; - buttonSize.setHeight(qMax(8, spinbox->rect.height() - frameThickness)); + buttonSize.setHeight(qMin(maxSize, qMax(8, spinbox->rect.height() - frameThickness))); //width should at least be equal to height - buttonSize.setWidth(qMax(buttonSize.height(), buttonWidth)); + 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(); + // Normally spinbuttons should be side-by-side, but if spinbox grows very big + // and spinbuttons reach their maximum size, they can be deployed one top of the other. + const bool sideBySide = (buttonSize.height() * 2 < spinbox->rect.height()) ? false : true; + const int y = frameThickness + spinbox->rect.y() + + (spinbox->rect.height() - (sideBySide ? 1 : 2) * buttonSize.height()) / 2; + const int x = spinbox->rect.x() + + spinbox->rect.width() - frameThickness - (sideBySide ? 2 : 1) * buttonSize.width(); switch (scontrol) { case SC_SpinBoxUp: @@ -2578,7 +2652,9 @@ case SC_SpinBoxDown: if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons) return QRect(); - ret = QRect(x + buttonSize.width(), y, buttonSize.width(), buttonSize.height()); + ret = QRect(x + (sideBySide ? buttonSize.width() : 0), + y + (sideBySide ? 0 : buttonSize.height()), + buttonSize.width(), buttonSize.height()); break; case SC_SpinBoxEditField: if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons) @@ -2634,6 +2710,19 @@ height - 2 * frameThickness); } break; + case SC_ComboBoxListBoxPopup: { + const QRect desktopContent = QApplication::desktop()->availableGeometry(); + + // take the size of this and position bottom above available area + QRect popupRect; + const int width = desktopContent.width() - pixelMetric(PM_LayoutRightMargin) - pixelMetric(PM_LayoutLeftMargin); + popupRect.setWidth(width); + popupRect.setHeight(desktopContent.height()); //combobox resets height anyway based on content + popupRect.setBottom(desktopContent.bottom()); + popupRect.translate(pixelMetric(PM_LayoutLeftMargin), 0); + ret = popupRect; + } + break; default: break; } @@ -2708,11 +2797,10 @@ 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); - ret = lineEditRect; + // a bit indented (8 pixels). + const int KLineEditDefaultIndention = 8; + ret = visualRect( + opt->direction, opt->rect, opt->rect.adjusted(KLineEditDefaultIndention, 0, 0, 0)); } break; case SE_TabBarTearIndicator: @@ -2788,9 +2876,13 @@ ret = menuItem->rect; if (element == SE_ItemViewItemDecoration) { - if (menuItem->direction == Qt::RightToLeft) - ret.translate(ret.width()-indicatorWidth, 0); - ret.setWidth(indicatorWidth); + if (menuItem->icon.isNull()) { + ret = QRect(); + } else { + if (menuItem->direction == Qt::RightToLeft) + ret.translate(ret.width()-indicatorWidth, 0); + ret.setWidth(indicatorWidth); + } } else { ret = menuItem->rect; if (!menuItem->icon.isNull()) @@ -2850,9 +2942,9 @@ if (qstyleoption_cast(opt)) { // Subtract area needed for line if (opt->state & State_Horizontal) - ret.setHeight(ret.height() - QS60StylePrivate::pixelMetric(PM_Custom_BoldLineWidth)); + ret.setHeight(ret.height() - QS60StylePrivate::pixelMetric(PM_BoldLineWidth)); else - ret.setWidth(ret.width() - QS60StylePrivate::pixelMetric(PM_Custom_ThinLineWidth)); + ret.setWidth(ret.width() - QS60StylePrivate::pixelMetric(PM_ThinLineWidth)); } ret = visualRect(opt->direction, opt->rect, ret); break; @@ -3163,7 +3255,7 @@ /*! \internal - Handle the timer \a event. + Handle the timer \a event. */ void QS60Style::timerEvent(QTimerEvent *event) {