Changeset 846 for trunk/src/gui/styles/qs60style.cpp
- Timestamp:
- May 5, 2011, 5:36:53 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/vendor/nokia/qt/4.7.2 (added) merged: 845 /branches/vendor/nokia/qt/current merged: 844 /branches/vendor/nokia/qt/4.6.3 removed
- Property svn:mergeinfo changed
-
trunk/src/gui/styles/qs60style.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 97 97 {360,640,1,19,"NHD Landscape"}, 98 98 {640,360,1,19,"NHD Portrait"}, 99 {352,800,1,12,"E90 Landscape"} 99 {352,800,1,12,"E90 Landscape"}, 100 {480,640,1,19,"VGA Landscape"} 100 101 // *** End of generated data *** 101 102 }; … … 105 106 const short QS60StylePrivate::data[][MAX_PIXELMETRICS] = { 106 107 // *** generated pixel metrics *** 107 {5,0,-909,0,0,2,0,0,-1,7,12,22,15,15,7,198,-909,-909,-909,20,13,2,0,0,21,7,18,30,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}, 108 {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,28,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}, 109 {7,0,-909,0,0,2,0,0,-1,25,69,46,37,37,9,258,-909,-909,-909,23,19,26,0,0,32,25,72,44,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}, 110 {7,0,-909,0,0,2,0,0,-1,25,68,46,37,37,9,258,-909,-909,-909,31,19,6,0,0,32,25,60,52,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}, 111 {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,30,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} 108 {5,0,-909,0,0,2,0,2,-1,7,12,22,15,15,7,198,-909,-909,-909,20,13,2,0,0,21,7,18,30,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}, 109 {5,0,-909,0,0,1,0,2,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,8,27,28,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}, 110 {7,0,-909,0,0,2,0,5,-1,25,69,46,37,37,9,258,-909,-909,-909,23,19,26,0,0,32,25,72,44,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,3,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}, 111 {7,0,-909,0,0,2,0,5,-1,25,68,46,37,37,9,258,-909,-909,-909,31,19,6,0,0,32,25,60,52,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,3,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}, 112 {7,0,-909,0,0,2,0,2,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,7,32,30,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}, 113 {9,0,-909,0,0,2,0,5,-1,34,99,76,51,51,25,352,-909,-909,-909,29,25,7,0,0,43,34,42,76,7,7,2,-909,-909,0,9,14,0,23,39,30,30,37,37,9,391,40,0,-909,-909,-909,-909,0,0,29,2,-909,0,0,-909,29,-909,-909,-909,-909,115,37,96,48,96,19,19,9,1,25,-909,9,101,24,9,0,7,7,7,16,7,7,-909,3,-909,-909,-909,-909,9,9,3,1,184} 112 114 // *** End of generated data *** 113 115 }; … … 136 138 {SE_ToolTip, QS60StyleEnums::SP_QsnFrPopupPreviewCenter}, 137 139 {SE_ToolBar, QS60StyleEnums::SP_QsnFrPopupSubCenter}, 138 {SE_ToolBarButton, QS60StyleEnums::SP_Q snFrSctrlButtonCenter},139 {SE_ToolBarButtonPressed, QS60StyleEnums::SP_Q snFrSctrlButtonCenterPressed},140 {SE_ToolBarButton, QS60StyleEnums::SP_QgnFrSctrlButtonCenter}, 141 {SE_ToolBarButtonPressed, QS60StyleEnums::SP_QgnFrSctrlButtonCenterPressed}, 140 142 {SE_PanelBackground, QS60StyleEnums::SP_QsnFrSetOptCenter}, 141 143 {SE_ButtonInactive, QS60StyleEnums::SP_QsnFrButtonCenterInactive}, 142 144 {SE_Editor, QS60StyleEnums::SP_QsnFrInputCenter}, 143 145 {SE_TableItemPressed, QS60StyleEnums::SP_QsnFrGridCenterPressed}, 144 {SE_ListItemPressed, QS60StyleEnums::SP_QsnFrList Pressed},146 {SE_ListItemPressed, QS60StyleEnums::SP_QsnFrListCenterPressed}, 145 147 }; 146 148 … … 155 157 clearCaches(); //deletes also background image 156 158 deleteThemePalette(); 159 #ifdef Q_WS_S60 160 removeAnimations(); 161 #endif 157 162 } 158 163 … … 403 408 break; 404 409 case CC_ThemeChange: 405 m_colorCache.clear();406 410 QPixmapCache::clear(); 411 #ifdef Q_WS_S60 412 deleteStoredSettings(); 413 #endif 407 414 deleteBackground(); 408 415 break; 409 416 case CC_UndefinedChange: 410 417 default: 411 m_colorCache.clear();412 418 m_mappedFontsCache.clear(); 413 419 QPixmapCache::clear(); … … 417 423 } 418 424 419 // Since S60Style has 'button' and 'tooltip' as a graphic, we don't have any native color which to use 420 // for QPalette::Button and QPalette::ToolTipBase. Therefore S60Style needs to guesstimate 421 // palette colors by calculating average rgb values for button pixels. 422 // Returns Qt::black if there is an issue with the graphics (image is NULL, or no bits() found). 423 QColor QS60StylePrivate::colorFromFrameGraphics(SkinFrameElements frame) const 424 { 425 const bool cachedColorExists = m_colorCache.contains(frame); 426 if (!cachedColorExists) { 427 const int frameCornerWidth = pixelMetric(PM_FrameCornerWidth); 428 const int frameCornerHeight = pixelMetric(PM_FrameCornerHeight); 429 Q_ASSERT(2 * frameCornerWidth < 32); 430 Q_ASSERT(2 * frameCornerHeight < 32); 431 432 const QImage frameImage = QS60StylePrivate::frame(frame, QSize(32, 32)).toImage(); 433 Q_ASSERT(frameImage.bytesPerLine() > 0); 434 if (frameImage.isNull()) 435 return Qt::black; 436 437 const QRgb *pixelRgb = (const QRgb*)frameImage.bits(); 438 const int pixels = frameImage.byteCount()/sizeof(QRgb); 439 440 int estimatedRed = 0; 441 int estimatedGreen = 0; 442 int estimatedBlue = 0; 443 444 int skips = 0; 445 int estimations = 0; 446 447 const int topBorderLastPixel = frameCornerHeight*frameImage.width() - 1; 448 const int bottomBorderFirstPixel = frameImage.width() * frameImage.height() - frameCornerHeight*frameImage.width() - 1; 449 const int rightBorderFirstPixel = frameImage.width() - frameCornerWidth; 450 const int leftBorderLastPixel = frameCornerWidth; 451 452 while ((skips + estimations) < pixels) { 453 if ((skips + estimations) > topBorderLastPixel && 454 (skips + estimations) < bottomBorderFirstPixel) { 455 for (int rowIndex = 0; rowIndex < frameImage.width(); rowIndex++) { 456 if (rowIndex > leftBorderLastPixel && 457 rowIndex < rightBorderFirstPixel) { 458 estimatedRed += qRed(*pixelRgb); 459 estimatedGreen += qGreen(*pixelRgb); 460 estimatedBlue += qBlue(*pixelRgb); 461 } 462 pixelRgb++; 463 estimations++; 425 QColor QS60StylePrivate::calculatedColor(SkinFrameElements frame) const 426 { 427 const int frameCornerWidth = pixelMetric(PM_FrameCornerWidth); 428 const int frameCornerHeight = pixelMetric(PM_FrameCornerHeight); 429 Q_ASSERT(2 * frameCornerWidth < 32); 430 Q_ASSERT(2 * frameCornerHeight < 32); 431 432 const QImage frameImage = QS60StylePrivate::frame(frame, QSize(32, 32)).toImage(); 433 Q_ASSERT(frameImage.bytesPerLine() > 0); 434 if (frameImage.isNull()) 435 return Qt::black; 436 437 const QRgb *pixelRgb = (const QRgb*)frameImage.constBits(); 438 const int pixels = frameImage.byteCount() / sizeof(QRgb); 439 440 int estimatedRed = 0; 441 int estimatedGreen = 0; 442 int estimatedBlue = 0; 443 444 int skips = 0; 445 int estimations = 0; 446 447 const int topBorderLastPixel = frameCornerHeight * frameImage.width() - 1; 448 const int bottomBorderFirstPixel = frameImage.width() * frameImage.height() - topBorderLastPixel; 449 const int rightBorderFirstPixel = frameImage.width() - frameCornerWidth; 450 const int leftBorderLastPixel = frameCornerWidth; 451 452 while ((skips + estimations) < pixels) { 453 if ((skips + estimations) > topBorderLastPixel && 454 (skips + estimations) < bottomBorderFirstPixel) { 455 for (int rowIndex = 0; rowIndex < frameImage.width(); rowIndex++) { 456 if (rowIndex > leftBorderLastPixel && 457 rowIndex < rightBorderFirstPixel) { 458 estimatedRed += qRed(*pixelRgb); 459 estimatedGreen += qGreen(*pixelRgb); 460 estimatedBlue += qBlue(*pixelRgb); 464 461 } 465 } else {466 462 pixelRgb++; 467 skips++; 468 } 469 } 470 QColor frameColor(estimatedRed/estimations, estimatedGreen/estimations, estimatedBlue/estimations); 471 m_colorCache.insert(frame, frameColor); 472 return !estimations ? Qt::black : frameColor; 473 } else { 474 return m_colorCache.value(frame); 475 } 476 463 estimations++; 464 } 465 } else { 466 pixelRgb++; 467 skips++; 468 } 469 } 470 QColor frameColor(estimatedRed/estimations, estimatedGreen/estimations, estimatedBlue/estimations); 471 return !estimations ? Qt::black : frameColor; 477 472 } 478 473 … … 487 482 { 488 483 return m_themePalette; 484 } 485 486 bool QS60StylePrivate::equalToThemePalette(QColor color, QPalette::ColorRole role) 487 { 488 if (!m_themePalette) 489 return false; 490 if (color == m_themePalette->color(role)) 491 return true; 492 return false; 493 } 494 495 bool QS60StylePrivate::equalToThemePalette(qint64 cacheKey, QPalette::ColorRole role) 496 { 497 if (!m_themePalette) 498 return false; 499 if (cacheKey == m_themePalette->brush(role).texture().cacheKey()) 500 return true; 501 return false; 489 502 } 490 503 … … 711 724 // set as transparent so that styled full screen theme background is visible 712 725 palette->setBrush(QPalette::Base, Qt::transparent); 713 // set button and tooltipbase based on pixel colors 726 // set button color based on pixel colors 727 #ifndef Q_WS_S60 728 //For emulated style, just calculate the color every time 729 const QColor buttonColor = calculatedColor(SF_ButtonNormal); 730 #else 714 731 const QColor buttonColor = colorFromFrameGraphics(SF_ButtonNormal); 732 #endif 715 733 palette->setColor(QPalette::Button, buttonColor); 716 const QColor toolTipColor = colorFromFrameGraphics(SF_ToolTip);717 palette->setColor(QPalette::ToolTipBase, toolTipColor);718 734 palette->setColor(QPalette::Light, palette->color(QPalette::Button).lighter()); 719 735 palette->setColor(QPalette::Dark, palette->color(QPalette::Button).darker()); … … 817 833 QApplication::setPalette(widgetPalette, "QLineEdit"); 818 834 QApplication::setPalette(widgetPalette, "QTextEdit"); 819 widgetPalette = *palette;820 821 widgetPalette.setColor(QPalette::HighlightedText,822 s60Color(QS60StyleEnums::CL_QsnTextColors, 24, 0));823 835 QApplication::setPalette(widgetPalette, "QComboBox"); 836 QApplication::setPalette(widgetPalette, "QSpinBox"); 824 837 widgetPalette = *palette; 825 838 … … 1061 1074 QStyleOptionFrame buttonOption; 1062 1075 buttonOption.QStyleOption::operator=(*cmb); 1063 const int max Height = cmbxFrame.height();1064 const int maxWidth = cmbxFrame.width() - cmbxEditField.width();1076 const int maxButtonSide = cmbxFrame.width() - cmbxEditField.width(); 1077 const int newTop = cmbxEditField.center().y() - maxButtonSide / 2; 1065 1078 const int topLeftPoint = direction ? 1066 (cmbxEditField.right() + 1) : (cmbxEditField.left() + 1 - max Width);1067 const QRect buttonRect(topLeftPoint, cmbxEditField.top(), maxWidth, maxHeight);1079 (cmbxEditField.right() + 1) : (cmbxEditField.left() + 1 - maxButtonSide); 1080 const QRect buttonRect(topLeftPoint, newTop, maxButtonSide, maxButtonSide); 1068 1081 buttonOption.rect = buttonRect; 1069 1082 buttonOption.state = cmb->state; … … 1098 1111 State mflags = bflags; 1099 1112 if (toolBtn->state & State_Sunken) { 1100 if (toolBtn->activeSubControls & SC_ToolButton) 1101 bflags |= State_Sunken; 1113 bflags |= State_Sunken; 1102 1114 mflags |= State_Sunken; 1103 1115 } … … 1115 1127 tool.rect = button.unite(menuRect); 1116 1128 tool.state = bflags; 1117 const QToolButton *toolButtonWidget = qobject_cast<const QToolButton *>(widget);1118 const QS60StylePrivate::SkinElements element =1119 ((toolButtonWidget && toolButtonWidget->isDown()) || (option->state & State_Sunken)) ?1120 QS60StylePrivate::SE_ToolBarButtonPressed : QS60StylePrivate::SE_ToolBarButton;1121 QS60StylePrivate::drawSkinElement(element, painter, tool.rect, flags);1122 1129 drawPrimitive(PE_PanelButtonTool, &tool, painter, widget); 1123 1130 } … … 1435 1442 const QAbstractItemView *itemView = qobject_cast<const QAbstractItemView *>(widget); 1436 1443 1437 // draw themed background for table unless background brush has been defined. 1444 const bool singleSelection = itemView && 1445 ((itemView->selectionMode() == QAbstractItemView::SingleSelection || 1446 itemView->selectionMode() == QAbstractItemView::NoSelection)); 1447 const bool selectItems = itemView && (itemView->selectionBehavior() == QAbstractItemView::SelectItems); 1448 1449 // draw themed background for itemview unless background brush has been defined. 1438 1450 if (vopt->backgroundBrush == Qt::NoBrush) { 1439 1451 if (itemView) { 1452 //With single item selection, use highlight focus as selection indicator. 1453 if (singleSelection && isSelected){ 1454 voptAdj.state = voptAdj.state | State_HasFocus; 1455 if (!hasFocus && selectItems) { 1456 painter->save(); 1457 painter->setOpacity(0.5); 1458 } 1459 } 1440 1460 drawPrimitive(PE_PanelItemViewItem, &voptAdj, painter, widget); 1461 if (singleSelection && isSelected && !hasFocus && selectItems) 1462 painter->restore(); 1441 1463 } 1442 1464 } else { QCommonStyle::drawPrimitive(PE_PanelItemViewItem, &voptAdj, painter, widget);} … … 1447 1469 voptAdj.icon.paint(painter, iconRect, voptAdj.decorationAlignment, mode, state); 1448 1470 1449 // Draw selection check mark. Show check mark only in multi selection modes. 1450 if (itemView) { 1451 const bool singleSelection = 1452 (itemView->selectionMode() == QAbstractItemView::SingleSelection || 1453 itemView->selectionMode() == QAbstractItemView::NoSelection)|| 1454 (itemView->selectionModel()->selectedIndexes().count() < 2 ); 1455 1456 const bool selectItemsOnly = (itemView->selectionBehavior() == QAbstractItemView::SelectItems); 1457 1471 // Draw selection check mark or checkbox 1472 if (itemView && (!singleSelection || (vopt->features & QStyleOptionViewItemV2::HasCheckIndicator))) { 1458 1473 const QRect selectionRect = subElementRect(SE_ItemViewItemCheckIndicator, &voptAdj, widget); 1459 1474 … … 1462 1477 checkMarkOption.rect = selectionRect; 1463 1478 // Draw selection mark. 1464 if (isSelected && !singleSelection && selectItemsOnly) {1479 if (isSelected && selectItems) { 1465 1480 proxy()->drawPrimitive(PE_IndicatorViewItemCheck, &checkMarkOption, painter, widget); 1466 1481 // @todo: this should happen in the rect retrievel i.e. subElementRect() 1467 1482 if (textRect.right() > selectionRect.left()) 1468 1483 textRect.setRight(selectionRect.left()); 1469 } else if (singleSelection && 1470 voptAdj.features & QStyleOptionViewItemV2::HasCheckIndicator) { 1484 } else if (voptAdj.features & QStyleOptionViewItemV2::HasCheckIndicator) { 1471 1485 checkMarkOption.state = checkMarkOption.state & ~State_HasFocus; 1472 1486 … … 1488 1502 // draw the text 1489 1503 if (!voptAdj.text.isEmpty()) { 1490 if ( isSelected || hasFocus)1504 if (hasFocus) 1491 1505 painter->setPen(voptAdj.palette.highlightedText().color()); 1492 1506 else … … 1751 1765 const bool enabled = optionMenuItem.state & State_Enabled; 1752 1766 const bool checkable = optionMenuItem.checkType != QStyleOptionMenuItem::NotCheckable; 1767 bool ignoreCheckMark = false; 1768 1769 #ifndef QT_NO_COMBOBOX 1770 if (qobject_cast<const QComboBox*>(widget)) 1771 ignoreCheckMark = true; //ignore the checkmarks provided by the QComboMenuDelegate 1772 #endif 1753 1773 1754 1774 uint text_flags = Qt::AlignLeading | Qt::TextShowMnemonic | Qt::TextDontClip … … 1757 1777 text_flags |= Qt::TextHideMnemonic; 1758 1778 1759 const bool selected = (option->state & State_Selected) && (option->state & State_Enabled);1760 if (selected)1761 QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ListHighlight, painter, option->rect, flags);1762 1763 1779 QRect iconRect = subElementRect(SE_ItemViewItemDecoration, &optionMenuItem, widget); 1764 1780 QRect textRect = subElementRect(SE_ItemViewItemText, &optionMenuItem, widget); 1765 1781 1766 //todo: move the vertical spacing stuff into subElementRect 1782 QStyleOptionMenuItem optionCheckBox; 1783 1784 //Regardless of checkbox visibility, make room for it, this mirrors native implementation, 1785 //where text and icon placement is static regardless of content of menu item. 1786 optionCheckBox.QStyleOptionMenuItem::operator=(*menuItem); 1787 optionCheckBox.rect.setWidth(pixelMetric(PM_IndicatorWidth)); 1788 optionCheckBox.rect.setHeight(pixelMetric(PM_IndicatorHeight)); 1789 1767 1790 const int vSpacing = QS60StylePrivate::pixelMetric(PM_LayoutVerticalSpacing); 1768 if (checkable){ 1769 const int hSpacing = QS60StylePrivate::pixelMetric(PM_LayoutHorizontalSpacing); 1770 QStyleOptionMenuItem optionCheckBox; 1771 optionCheckBox.QStyleOptionMenuItem::operator=(*menuItem); 1772 optionCheckBox.rect.setWidth(pixelMetric(PM_IndicatorWidth)); 1773 optionCheckBox.rect.setHeight(pixelMetric(PM_IndicatorHeight)); 1774 optionCheckBox.rect.moveCenter(QPoint( 1775 optionCheckBox.rect.center().x(), 1776 menuItem->rect.center().y())); 1777 const int moveByX = optionCheckBox.rect.width() + vSpacing; 1778 if (optionMenuItem.direction == Qt::LeftToRight) { 1779 textRect.translate(moveByX, 0); 1780 iconRect.translate(moveByX, 0); 1781 iconRect.setWidth(iconRect.width() + vSpacing); 1782 textRect.setWidth(textRect.width() - moveByX - vSpacing); 1783 optionCheckBox.rect.translate(vSpacing >> 1, hSpacing >> 1); 1784 } else { 1785 textRect.setWidth(textRect.width() - moveByX); 1786 iconRect.setWidth(iconRect.width() + vSpacing); 1787 iconRect.translate(-optionCheckBox.rect.width() - vSpacing, 0); 1788 optionCheckBox.rect.translate(textRect.width() + iconRect.width(), 0); 1789 } 1791 //The vertical spacing is doubled; it needs one spacing to separate checkbox from 1792 //highlight and then it needs one to separate it whatever is shown after it (text/icon/both). 1793 const int moveByX = optionCheckBox.rect.width() + 2 * vSpacing; 1794 optionCheckBox.rect.moveCenter(QPoint( 1795 optionCheckBox.rect.center().x() + moveByX >> 1, 1796 menuItem->rect.center().y())); 1797 1798 if (optionMenuItem.direction != Qt::LeftToRight) 1799 optionCheckBox.rect.translate(textRect.width() + iconRect.width(), 0); 1800 1801 1802 const bool selected = (option->state & State_Selected) && (option->state & State_Enabled); 1803 if (selected) { 1804 const int spacing = ignoreCheckMark ? (vSpacing + QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth)) : 0; 1805 const int start = optionMenuItem.rect.left() + spacing; 1806 const int end = optionMenuItem.rect.right() - spacing; 1807 //-1 adjustment to avoid highlight being on top of possible separator item 1808 const QRect highlightRect = QRect( 1809 QPoint(start, option->rect.top()), 1810 QPoint(end, option->rect.bottom() - 1)); 1811 QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ListHighlight, painter, highlightRect, flags); 1812 } 1813 1814 if (checkable && !ignoreCheckMark) 1790 1815 drawPrimitive(PE_IndicatorMenuCheckMark, &optionCheckBox, painter, widget); 1791 } 1816 1792 1817 //draw icon and/or checkState 1793 1818 QPixmap pix = menuItem->icon.pixmap(pixelMetric(PM_SmallIconSize), … … 1800 1825 else 1801 1826 textRect.translate(-vSpacing, 0); 1802 textRect.setWidth(textRect.width() -vSpacing);1827 textRect.setWidth(textRect.width() - vSpacing); 1803 1828 } 1804 1829 … … 1818 1843 painter->save(); 1819 1844 painter->setPen(option->palette.windowText().color()); 1820 QS60StylePrivate::drawSkinPart(QS60StyleEnums::SP_QgnIndiSub Menu, painter, arrowOptions.rect,1845 QS60StylePrivate::drawSkinPart(QS60StyleEnums::SP_QgnIndiSubmenu, painter, arrowOptions.rect, 1821 1846 (flags | QS60StylePrivate::SF_ColorSkinned | arrowDirection)); 1822 1847 painter->restore(); … … 1838 1863 optionMenuItem.palette, enabled, 1839 1864 optionMenuItem.text, QPalette::Text); 1865 1866 //In Sym^3, native menu items have "lines" between them 1867 if (QS60StylePrivate::isSingleClickUi()) { 1868 const QColor lineColorAlpha = QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors, 15, 0); 1869 const int spacing = QS60StylePrivate::pixelMetric(PM_FrameCornerWidth); 1870 //native platform sets each color byte to same value for "line 16" which just defines alpha for 1871 //menuitem lines; lets use first byte "red". 1872 QColor lineColor = optionMenuItem.palette.text().color(); 1873 if (lineColorAlpha.isValid()) 1874 lineColor.setAlpha(lineColorAlpha.red()); 1875 painter->save(); 1876 painter->setPen(lineColor); 1877 1878 const int lineStartX = optionMenuItem.rect.left() + (QS60StylePrivate::pixelMetric(PM_FrameCornerWidth) - 2) + spacing; 1879 const int lineEndX = optionMenuItem.rect.right() - (QS60StylePrivate::pixelMetric(PM_FrameCornerWidth) - 2) - spacing; 1880 painter->drawLine(QPoint(lineStartX, optionMenuItem.rect.bottom()), QPoint(lineEndX, optionMenuItem.rect.bottom())); 1881 painter->restore(); 1882 } 1840 1883 if (!enabled) 1841 1884 painter->restore(); … … 1952 1995 if (const QTextEdit *textEdit = qobject_cast<const QTextEdit *>(widget)) { 1953 1996 const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(option); 1954 if ( QS60StylePrivate::canDrawThemeBackground(frame->palette.base(), widget))1997 if (frame && QS60StylePrivate::canDrawThemeBackground(frame->palette.base(), widget)) 1955 1998 QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_Editor, painter, option->rect, flags); 1956 1999 else … … 2019 2062 break; 2020 2063 case CE_Splitter: 2021 if (option->state & State_Sunken && option->state & State_Enabled ) {2064 if (option->state & State_Sunken && option->state & State_Enabled && QS60StylePrivate::themePalette()) { 2022 2065 painter->save(); 2023 2066 painter->setOpacity(0.5); … … 2046 2089 //Draw themed highlight to radiobuttons and checkboxes. 2047 2090 //For other widgets skip, unless palette has been modified. In that case, draw with commonstyle. 2048 if ( option->palette.highlight().color() == QS60StylePrivate::themePalette()->highlight().color()) {2091 if (QS60StylePrivate::equalToThemePalette(option->palette.highlight().color(), QPalette::Highlight)) { 2049 2092 if ((qstyleoption_cast<const QStyleOptionFocusRect *>(option) && 2050 2093 (qobject_cast<const QRadioButton *>(widget) || qobject_cast<const QCheckBox *>(widget)))) … … 2078 2121 painter->save(); 2079 2122 2080 const QColor themeColor = QS60StylePrivate::themePalette()->windowText().color(); 2081 const QColor windowTextColor = option->palette.windowText().color(); 2082 2083 if (themeColor != windowTextColor) 2084 painter->setPen(windowTextColor); 2123 if (QS60StylePrivate::equalToThemePalette(option->palette.windowText().color(), QPalette::WindowText)) 2124 painter->setPen(option->palette.windowText().color()); 2085 2125 2086 2126 QS60StylePrivate::drawSkinPart(skinPart, painter, option->rect, flags | QS60StylePrivate::SF_ColorSkinned ); … … 2146 2186 case PE_FrameButtonBevel: 2147 2187 if (QS60StylePrivate::canDrawThemeBackground(option->palette.base(), widget)) { 2148 const bool isPressed = option->state & State_Sunken; 2149 const QS60StylePrivate::SkinElements skinElement = 2150 isPressed ? QS60StylePrivate::SE_ButtonPressed : QS60StylePrivate::SE_ButtonNormal; 2188 const bool isPressed = (option->state & State_Sunken) || (option->state & State_On); 2189 QS60StylePrivate::SkinElements skinElement; 2190 if (element == PE_PanelButtonTool) 2191 skinElement = isPressed ? QS60StylePrivate::SE_ToolBarButtonPressed : QS60StylePrivate::SE_ToolBarButton; 2192 else 2193 skinElement = isPressed ? QS60StylePrivate::SE_ButtonPressed : QS60StylePrivate::SE_ButtonNormal; 2151 2194 QS60StylePrivate::drawSkinElement(skinElement, painter, option->rect, flags); 2152 2195 } else { … … 2232 2275 //Need extra check since dialogs have their own theme background 2233 2276 if (QS60StylePrivate::canDrawThemeBackground(option->palette.base(), widget) && 2234 option->palette.window().texture().cacheKey() == 2235 QS60StylePrivate::m_themePalette->window().texture().cacheKey()) 2277 QS60StylePrivate::equalToThemePalette(option->palette.window().texture().cacheKey(), QPalette::Window)) 2278 //todo: for combobox listviews, the background should include area for menu scrollers, 2279 //but this produces drawing issues as we need to turn clipping off. 2236 2280 QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_PopupBackground, painter, option->rect, flags); 2237 2281 else … … 2278 2322 const bool isPressed = QS60StylePrivate::isWidgetPressed(widget); 2279 2323 2280 if ( option->palette.highlight().color() == QS60StylePrivate::themePalette()->highlight().color()) {2324 if (QS60StylePrivate::equalToThemePalette(option->palette.highlight().color(), QPalette::Highlight)) { 2281 2325 QRect highlightRect = vopt->rect.adjusted(1,1,-1,-1); 2282 2326 const QAbstractItemView *itemView = qobject_cast<const QAbstractItemView *>(widget); … … 2284 2328 itemView ? itemView->selectionBehavior() : QAbstractItemView::SelectItems; 2285 2329 // Set the draw area for highlights (focus, select rect or pressed rect) 2286 if (hasFocus || is Selected || isPressed) {2330 if (hasFocus || isPressed) { 2287 2331 if (selectionBehavior != QAbstractItemView::SelectItems) { 2288 2332 // set highlight rect so that it is continuous from cell to cell, yet sligthly … … 2310 2354 2311 2355 QS60StylePrivate::SkinElements element; 2356 bool themeGraphicDefined = false; 2312 2357 QRect elementRect = option->rect; 2313 2358 2314 2359 //draw item is drawn as pressed, if it already has focus. 2315 if (isPressed && (hasFocus || isSelected)) { 2360 if (isPressed && hasFocus) { 2361 themeGraphicDefined = true; 2316 2362 element = tableView ? QS60StylePrivate::SE_TableItemPressed : QS60StylePrivate::SE_ListItemPressed; 2317 2363 } else if (hasFocus || (isSelected && selectionBehavior != QAbstractItemView::SelectItems)) { 2318 2364 element = QS60StylePrivate::SE_ListHighlight; 2319 2365 elementRect = highlightRect; 2366 themeGraphicDefined = true; 2320 2367 } 2321 QS60StylePrivate::drawSkinElement(element, painter, elementRect, flags); 2368 if (themeGraphicDefined) 2369 QS60StylePrivate::drawSkinElement(element, painter, elementRect, flags); 2322 2370 } else { 2323 2371 QCommonStyle::drawPrimitive(element, option, painter, widget); … … 2399 2447 #ifndef QT_NO_ITEMVIEWS 2400 2448 if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option)) { 2401 if ( vopt->palette.base().texture().cacheKey() != QS60StylePrivate::m_themePalette->base().texture().cacheKey()) {2449 if (!QS60StylePrivate::equalToThemePalette(vopt->palette.base().texture().cacheKey(), QPalette::Base)) { 2402 2450 //QPalette::Base has been changed, let commonstyle draw the item 2403 2451 commonStyleDraws = true; … … 2470 2518 } 2471 2519 2472 if (widget && (metric == PM_LayoutTopMargin ))2520 if (widget && (metric == PM_LayoutTopMargin || metric == PM_LayoutLeftMargin || metric == PM_LayoutRightMargin)) 2473 2521 if (widget->windowType() == Qt::Dialog) 2474 //double the top layout marginfor dialogs, it is very close to real value2522 //double the layout margins (except bottom) for dialogs, it is very close to real value 2475 2523 //without having to define custom pixel metric 2476 2524 metricValue *= 2; 2477 2478 if (widget && (metric == PM_FocusFrameHMargin))2479 if (qobject_cast<const QTableView *>(widget))2480 //Halve the focus frame margin for table items2481 metricValue /= 2;2482 2525 2483 2526 return metricValue; … … 2497 2540 if (toolBtn->subControls & SC_ToolButtonMenu) 2498 2541 sz += QSize(pixelMetric(PM_MenuButtonIndicator), 0); 2542 2543 //Make toolbuttons in toolbar stretch the whole screen area 2544 if (widget && qobject_cast<const QToolBar *>(widget->parentWidget())) { 2545 const QToolBar *tb = qobject_cast<const QToolBar *>(widget->parentWidget()); 2546 const bool parentCanGrowHorizontally = !(tb->sizePolicy().horizontalPolicy() == QSizePolicy::Fixed || 2547 tb->sizePolicy().horizontalPolicy() == QSizePolicy::Maximum) && tb->orientation() == Qt::Horizontal; 2548 2549 if (parentCanGrowHorizontally) { 2550 int visibleButtons = 0; 2551 //Make the auto-stretch to happen only for horizontal orientation 2552 if (tb && tb->orientation() == Qt::Horizontal) { 2553 QList<QAction*> actionList = tb->actions(); 2554 for (int i = 0; i < actionList.count(); i++) { 2555 if (actionList.at(i)->isVisible()) 2556 visibleButtons++; 2557 } 2558 } 2559 2560 if (widget->parentWidget() && visibleButtons > 0) { 2561 QWidget *w = const_cast<QWidget *>(widget); 2562 int toolBarMaxWidth = 0; 2563 int totalMargin = 0; 2564 while (w) { 2565 //honor fixed width parents 2566 if (w->maximumWidth() == w->minimumWidth()) 2567 toolBarMaxWidth = qMax(toolBarMaxWidth, w->maximumWidth()); 2568 if (w->layout() && w->windowType() == Qt::Widget) { 2569 totalMargin += w->layout()->contentsMargins().left() + 2570 w->layout()->contentsMargins().right(); 2571 } 2572 w = w->parentWidget(); 2573 } 2574 totalMargin += 2 * pixelMetric(QStyle::PM_ToolBarFrameWidth); 2575 2576 if (toolBarMaxWidth == 0) 2577 toolBarMaxWidth = 2578 QApplication::desktop()->availableGeometry(widget->parentWidget()).width(); 2579 //Reduce the margins, toolbar frame, item spacing and internal margin from available area 2580 toolBarMaxWidth -= totalMargin; 2581 2582 //ensure that buttons are side-by-side and not on top of each other 2583 const int toolButtonWidth = (toolBarMaxWidth / visibleButtons) 2584 - pixelMetric(QStyle::PM_ToolBarItemSpacing) 2585 - pixelMetric(QStyle::PM_ToolBarItemMargin) 2586 //toolbar frame needs to be reduced again, since QToolBarLayout adds it for each toolbar action 2587 - 2 * pixelMetric(QStyle::PM_ToolBarFrameWidth) - 1; 2588 sz.setWidth(qMax(toolButtonWidth, sz.width())); 2589 } 2590 } 2591 } 2499 2592 break; 2500 2593 case CT_PushButton: … … 2549 2642 } 2550 2643 sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget); 2644 //native items have small empty areas at the beginning and end of menu item 2645 sz.setWidth(sz.width() + 2 * pixelMetric(PM_MenuHMargin) + 2 * QS60StylePrivate::pixelMetric(PM_FrameCornerWidth)); 2551 2646 if (QS60StylePrivate::isTouchSupported()) 2552 2647 //Make itemview easier to use in touch devices 2553 2648 //QCommonStyle does not adjust height with horizontal margin, it only adjusts width 2554 sz.setHeight(sz.height() + 2 * pixelMetric(PM_FocusFrameVMargin) );2649 sz.setHeight(sz.height() + 2 * pixelMetric(PM_FocusFrameVMargin) - 8); //QCommonstyle adds 8 to height that this style handles through PM values 2555 2650 break; 2556 2651 #ifndef QT_NO_COMBOBOX … … 2569 2664 break; 2570 2665 } 2666 if (!sz.isValid()) 2667 sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget); 2571 2668 return sz; 2572 2669 } … … 2790 2887 const int width = cmb->rect.width(); 2791 2888 const int height = cmb->rect.height(); 2792 const int buttonIconSize = QS60StylePrivate::pixelMetric(PM_ButtonIconSize);2793 2889 const int buttonMargin = cmb->frame ? 2 : 0; 2794 2890 // lets use spinbox frame here as well, as no combobox specific value available. 2795 2891 const int frameThickness = cmb->frame ? pixelMetric(PM_SpinBoxFrameWidth, cmb, widget) : 0; 2796 const int buttonWidth = qMax(cmb->rect.height(), buttonIconSize); 2797 2892 const int buttonMinSize = QS60StylePrivate::pixelMetric(PM_ButtonIconSize) + 2 * buttonMargin; 2798 2893 QSize buttonSize; 2799 buttonSize.setWidth(buttonWidth + 2 * buttonMargin); 2800 buttonSize.setHeight(qMax(8, (cmb->rect.height() >> 1) - frameThickness)); //buttons should be squares 2894 //allow button to grow to one fourth of the frame height, if the frame is really tall 2895 buttonSize.setHeight(qMin(height, qMax(width / 4, buttonMinSize))); 2896 buttonSize.setWidth(buttonSize.height()); 2801 2897 buttonSize = buttonSize.expandedTo(QApplication::globalStrut()); 2802 2898 switch (scontrol) { 2803 2899 case SC_ComboBoxArrow: { 2804 const int xposMod = cmb->rect.x() + width - buttonMargin - button Width;2900 const int xposMod = cmb->rect.x() + width - buttonMargin - buttonSize.width(); 2805 2901 const int ypos = cmb->rect.y(); 2806 ret.setRect(xposMod, ypos + buttonMargin, button Width, height - 2 * buttonMargin);2902 ret.setRect(xposMod, ypos + buttonMargin, buttonSize.width(), height - 2 * buttonMargin); 2807 2903 } 2808 2904 break; 2809 2905 case SC_ComboBoxEditField: { 2810 const int withFrameX = cmb->rect.x() + width - frameThickness - buttonSize.width(); 2811 ret = QRect( 2812 frameThickness, 2813 frameThickness, 2814 withFrameX - frameThickness, 2815 height - 2 * frameThickness); 2906 ret = QRect(0, 0, cmb->rect.x() + width - buttonSize.width(), height); 2816 2907 } 2817 2908 break; 2818 2909 case SC_ComboBoxListBoxPopup: { 2819 const QRect desktopContent = QApplication::desktop()->availableGeometry(); 2820 2821 // take the size of this and position bottom above available area 2822 QRect popupRect; 2823 const int width = desktopContent.width() - pixelMetric(PM_LayoutRightMargin) - pixelMetric(PM_LayoutLeftMargin); 2824 popupRect.setWidth(width); 2825 popupRect.setHeight(desktopContent.height()); //combobox resets height anyway based on content 2826 popupRect.setBottom(desktopContent.bottom()); 2827 popupRect.translate(pixelMetric(PM_LayoutLeftMargin), 0); 2828 ret = popupRect; 2910 ret = QApplication::desktop()->availableGeometry(); 2829 2911 } 2830 2912 break; … … 2957 3039 case SE_ItemViewItemDecoration: 2958 3040 if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) { 2959 const Q ListWidget *listItem = qobject_cast<const QListWidget*>(widget);3041 const QAbstractItemView *listItem = qobject_cast<const QAbstractItemView *>(widget); 2960 3042 const bool multiSelection = !listItem ? false : 2961 3043 listItem->selectionMode() == QAbstractItemView::MultiSelection || … … 2981 3063 ret = menuItem->rect; 2982 3064 3065 QRect checkBoxRect = checkable ? menuItem->rect : QRect(); 3066 if (checkable) { 3067 checkBoxRect.setWidth(pixelMetric(PM_IndicatorWidth)); 3068 checkBoxRect.setHeight(pixelMetric(PM_IndicatorHeight)); 3069 } 3070 3071 const int vSpacing = QS60StylePrivate::pixelMetric(PM_LayoutVerticalSpacing); 3072 //The vertical spacing is doubled; it needs one spacing to separate checkbox from 3073 //highlight and then it needs one to separate it whatever is shown after it (text/icon/both). 3074 const int moveByX = checkBoxRect.width() + 2 * vSpacing; 3075 2983 3076 if (element == SE_ItemViewItemDecoration) { 2984 3077 if (menuItem->icon.isNull()) { … … 2986 3079 } else { 2987 3080 if (menuItem->direction == Qt::RightToLeft) 2988 ret.translate(ret.width() - indicatorWidth, 0); 3081 ret.translate(ret.width() - indicatorWidth - moveByX, 0); 3082 else 3083 ret.translate(moveByX, 0); 2989 3084 ret.setWidth(indicatorWidth); 2990 3085 } 2991 3086 } else { 2992 ret = menuItem->rect; 2993 if (!menuItem->icon.isNull()) 3087 if (!menuItem->icon.isNull()) { 2994 3088 if (menuItem->direction == Qt::LeftToRight) 2995 3089 ret.adjust(indicatorWidth, 0, 0, 0); 2996 3090 else 2997 3091 ret.adjust(0, 0, -indicatorWidth, 0); 3092 } 3093 if (menuItem->direction == Qt::LeftToRight) 3094 ret.adjust(moveByX, 0, 0, 0); 3095 else 3096 ret.adjust(0, 0, -moveByX, 0); 2998 3097 2999 3098 // Make room for submenu indicator … … 3010 3109 case SE_ItemViewItemCheckIndicator: 3011 3110 if (const QStyleOptionViewItemV2 *vopt = qstyleoption_cast<const QStyleOptionViewItemV2 *>(opt)) { 3012 const Q ListWidget *listItem = qobject_cast<const QListWidget*>(widget);3111 const QAbstractItemView *listItem = qobject_cast<const QAbstractItemView *>(widget); 3013 3112 3014 3113 const bool singleSelection = listItem && … … 3073 3172 ret = opt->rect; 3074 3173 break; 3174 case SE_ProgressBarLabel: 3175 case SE_ProgressBarContents: 3176 case SE_ProgressBarGroove: 3177 ret = opt->rect; 3178 break; 3075 3179 default: 3076 3180 ret = QCommonStyle::subElementRect(element, opt, widget); … … 3322 3426 break; 3323 3427 case SP_ToolBarHorizontalExtensionButton: 3324 part = QS60StyleEnums::SP_QgnIndiSub Menu;3428 part = QS60StyleEnums::SP_QgnIndiSubmenu; 3325 3429 if (QApplication::layoutDirection() == Qt::RightToLeft) 3326 3430 adjustedFlags |= QS60StylePrivate::SF_PointSouth; … … 3328 3432 case SP_ToolBarVerticalExtensionButton: 3329 3433 adjustedFlags |= QS60StylePrivate::SF_PointEast; 3330 part = QS60StyleEnums::SP_QgnIndiSub Menu;3434 part = QS60StyleEnums::SP_QgnIndiSubmenu; 3331 3435 break; 3332 3436 … … 3361 3465 d->m_pressedWidget = w; 3362 3466 3363 if ( 3467 if (d->m_pressedWidget) 3364 3468 d->m_pressedWidget->update(); 3365 3469 } … … 3367 3471 } 3368 3472 case QEvent::MouseButtonRelease: { 3369 const QWidget *w = QApplication::widgetAt(QCursor::pos()); 3370 if (w && d->m_pressedWidget) { 3473 if (d->m_pressedWidget) { 3371 3474 d->m_pressedWidget->update(); 3372 3475 d->m_pressedWidget = 0;
Note:
See TracChangeset
for help on using the changeset viewer.