diff -r cc75c76972ee -r c0432d11811c src/gui/styles/qs60style.cpp --- a/src/gui/styles/qs60style.cpp Wed Apr 21 12:15:23 2010 +0300 +++ b/src/gui/styles/qs60style.cpp Wed Apr 21 20:15:53 2010 +0300 @@ -122,6 +122,8 @@ qint64 QS60StylePrivate::m_webPaletteKey = 0; +QPointer QS60StylePrivate::m_pressedWidget = 0; + const struct QS60StylePrivate::frameElementCenter QS60StylePrivate::m_frameElementsData[] = { {SE_ButtonNormal, QS60StyleEnums::SP_QsnFrButtonTbCenter}, {SE_ButtonPressed, QS60StyleEnums::SP_QsnFrButtonTbCenterPressed}, @@ -138,6 +140,8 @@ {SE_PanelBackground, QS60StyleEnums::SP_QsnFrSetOptCenter}, {SE_ButtonInactive, QS60StyleEnums::SP_QsnFrButtonCenterInactive}, {SE_Editor, QS60StyleEnums::SP_QsnFrInputCenter}, + {SE_TableItemPressed, QS60StyleEnums::SP_QsnFrGridCenterPressed}, + {SE_ListItemPressed, QS60StyleEnums::SP_QsnFrListPressed}, }; static const int frameElementsCount = @@ -294,6 +298,12 @@ case SE_DropArea: drawPart(QS60StyleEnums::SP_QgnGrafOrgBgGrid, painter, rect, flags | SF_PointNorth); break; + case SE_TableItemPressed: + drawFrame(SF_TableItemPressed, painter, rect, flags | SF_PointNorth); + break; + case SE_ListItemPressed: + drawFrame(SF_ListItemPressed, painter, rect, flags | SF_PointNorth); + break; default: break; } @@ -542,6 +552,7 @@ QRect endRect; if (orientation == Qt::Horizontal) { + startRect.setHeight(rect.height()); startRect.setWidth(qMin((rect.width() >> 1) - 1, startRect.width())); endRect = startRect.translated(rect.width() - startRect.width(), 0); middleRect.adjust(startRect.width(), 0, -startRect.width(), 0); @@ -551,6 +562,7 @@ endRect.adjust(overlap, 0, 0, 0); } } else { + startRect.setWidth(rect.width()); 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()); @@ -639,6 +651,8 @@ fontCategory = QS60StyleEnums::FC_Title; } else if (qobject_cast(widget)){ fontCategory = QS60StyleEnums::FC_Primary; + } else if (qobject_cast(widget)){ + fontCategory = QS60StyleEnums::FC_Primary; } if (fontCategory != QS60StyleEnums::FC_Undefined) { const bool resolveFontSize = widget->testAttribute(Qt::WA_SetFont) @@ -939,6 +953,11 @@ backgroundBrush.style() == Qt::NoBrush) ? true : false; } +bool QS60StylePrivate::isWidgetPressed(const QWidget *widget) +{ + return (widget && widget == m_pressedWidget); +} + /*! \class QS60Style \brief The QS60Style class provides a look and feel suitable for applications on S60. @@ -1357,14 +1376,13 @@ optionComboBox.palette.setColor(QPalette::Inactive, QPalette::WindowText, optionComboBox.palette.text().color() ); QRect editRect = subControlRect(CC_ComboBox, comboBox, SC_ComboBoxEditField, widget); - painter->save(); - painter->setClipRect(editRect); + const int frameW = proxy()->pixelMetric(PM_DefaultFrameWidth, option, widget); if (!comboBox->currentIcon.isNull()) { - QIcon::Mode mode = comboBox->state & State_Enabled ? QIcon::Normal : QIcon::Disabled; - QPixmap pixmap = comboBox->currentIcon.pixmap(comboBox->iconSize, mode); + const QIcon::Mode mode = comboBox->state & State_Enabled ? QIcon::Normal : QIcon::Disabled; + const QPixmap pixmap = comboBox->currentIcon.pixmap(comboBox->iconSize, mode); QRect iconRect(editRect); - iconRect.setWidth(comboBox->iconSize.width() + 4); + iconRect.setWidth(comboBox->iconSize.width() + frameW); iconRect = alignedRect(comboBox->direction, Qt::AlignLeft | Qt::AlignVCenter, iconRect.size(), editRect); @@ -1373,17 +1391,19 @@ drawItemPixmap(painter, iconRect, Qt::AlignCenter, pixmap); if (comboBox->direction == Qt::RightToLeft) - editRect.translate(-4 - comboBox->iconSize.width(), 0); + editRect.setRight(editRect.right() - frameW - comboBox->iconSize.width()); else - editRect.translate(comboBox->iconSize.width() + 4, 0); + editRect.setLeft(comboBox->iconSize.width() + frameW); } if (!comboBox->currentText.isEmpty() && !comboBox->editable) { + const Qt::TextElideMode elideMode = (comboBox->direction == Qt::LeftToRight) ? Qt::ElideRight : Qt::ElideLeft; + const QString text = comboBox->fontMetrics.elidedText(comboBox->currentText, elideMode, editRect.width()); + QCommonStyle::drawItemText(painter, editRect.adjusted(QS60StylePrivate::pixelMetric(PM_FrameCornerWidth), 0, -1, 0), visualAlignment(comboBox->direction, Qt::AlignLeft | Qt::AlignVCenter), - comboBox->palette, comboBox->state & State_Enabled, comboBox->currentText); + comboBox->palette, comboBox->state & State_Enabled, text); } - painter->restore(); } break; #endif //QT_NO_COMBOBOX @@ -1424,73 +1444,37 @@ // draw themed background for table unless background brush has been defined. if (vopt->backgroundBrush == Qt::NoBrush) { if (itemView) { - 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 indexLast = itemView->model()->index( - 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()); drawPrimitive(PE_PanelItemViewItem, &voptAdj, painter, widget); } } else { QCommonStyle::drawPrimitive(PE_PanelItemViewItem, &voptAdj, painter, widget);} - // draw the focus rect - if (isSelected || hasFocus ) { - QRect highlightRect = option->rect.adjusted(1,1,-1,-1); - QAbstractItemView::SelectionBehavior selectionBehavior = - itemView ? itemView->selectionBehavior() : QAbstractItemView::SelectItems; - if (selectionBehavior != QAbstractItemView::SelectItems) { - // set highlight rect so that it is continuous from cell to cell, yet sligthly - // smaller than cell rect - int xBeginning = 0, yBeginning = 0, xEnd = 0, yEnd = 0; - if (selectionBehavior == QAbstractItemView::SelectRows) { - yBeginning = 1; yEnd = -1; - if (vopt->viewItemPosition == QStyleOptionViewItemV4::Beginning) - xBeginning = 1; - else if (vopt->viewItemPosition == QStyleOptionViewItemV4::End) - xEnd = -1; - } else if (selectionBehavior == QAbstractItemView::SelectColumns) { - xBeginning = 1; xEnd = -1; - if (vopt->viewItemPosition == QStyleOptionViewItemV4::Beginning) - yBeginning = 1; - else if (vopt->viewItemPosition == QStyleOptionViewItemV4::End) - yEnd = -1; - } - highlightRect = option->rect.adjusted(xBeginning, yBeginning, xEnd, yEnd); - } - if (vopt->showDecorationSelected && - (vopt->palette.highlight().color() == QS60StylePrivate::themePalette()->highlight().color())) - QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ListHighlight, painter, highlightRect, flags); - else - painter->fillRect(highlightRect, vopt->palette.highlight()); - } - // draw the icon const QIcon::Mode mode = (voptAdj.state & State_Enabled) ? QIcon::Normal : QIcon::Disabled; - const QIcon::State state = voptAdj.state & State_Open ? QIcon::On : QIcon::Off; + 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. if (itemView) { const bool singleSelection = (itemView->selectionMode() == QAbstractItemView::SingleSelection || - itemView->selectionMode() == QAbstractItemView::NoSelection); + itemView->selectionMode() == QAbstractItemView::NoSelection)|| + (itemView->selectionModel()->selectedIndexes().count() < 2 ); + + const bool selectItemsOnly = (itemView->selectionBehavior() == QAbstractItemView::SelectItems); + const QRect selectionRect = subElementRect(SE_ItemViewItemCheckIndicator, &voptAdj, widget); QStyleOptionViewItemV4 checkMarkOption(voptAdj); - // Draw selection mark. - if (voptAdj.state & State_Selected && !singleSelection) { + if (selectionRect.isValid()) checkMarkOption.rect = selectionRect; - drawPrimitive(PE_IndicatorViewItemCheck, &checkMarkOption, painter, widget); - if ( textRect.right() > selectionRect.left() ) + // Draw selection mark. + if (isSelected && !singleSelection && selectItemsOnly) { + proxy()->drawPrimitive(PE_IndicatorViewItemCheck, &checkMarkOption, painter, widget); + // @todo: this should happen in the rect retrievel i.e. subElementRect() + if (textRect.right() > selectionRect.left()) textRect.setRight(selectionRect.left()); } else if (singleSelection && - voptAdj.features & QStyleOptionViewItemV2::HasCheckIndicator && - selectionRect.isValid()) { - checkMarkOption.rect = selectionRect; + voptAdj.features & QStyleOptionViewItemV2::HasCheckIndicator) { checkMarkOption.state = checkMarkOption.state & ~State_HasFocus; switch (vopt->checkState) { @@ -1562,7 +1546,6 @@ QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth); const int tabOverlap = QS60StylePrivate::pixelMetric(PM_TabBarTabOverlap) - borderThickness; - //todo: draw navi wipe behind tabbar - must be drawn with first draw if (skinElement==QS60StylePrivate::SE_TabBarTabEastInactive|| skinElement==QS60StylePrivate::SE_TabBarTabEastActive|| @@ -1666,7 +1649,7 @@ painter->drawPixmap(tr.left() + tabOverlap, tr.center().y() - (tabIcon.height() >> 1), tabIcon); - tr.setLeft(tr.left() + iconSize.width() + 4); + tr.setLeft(tr.left() + iconSize.width() + 4); //todo: magic four } QCommonStyle::drawItemText(painter, tr, alignment, optionTab.palette, tab->state & State_Enabled, tab->text, QPalette::WindowText); @@ -1763,6 +1746,9 @@ optionCheckBox.QStyleOptionMenuItem::operator=(*menuItem); optionCheckBox.rect.setWidth(pixelMetric(PM_IndicatorWidth)); optionCheckBox.rect.setHeight(pixelMetric(PM_IndicatorHeight)); + optionCheckBox.rect.moveCenter(QPoint( + optionCheckBox.rect.center().x(), + menuItem->rect.center().y())); const int moveByX = optionCheckBox.rect.width() + vSpacing; if (optionMenuItem.direction == Qt::LeftToRight) { textRect.translate(moveByX, 0); @@ -1985,14 +1971,14 @@ // 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)); + qMin(0, pixelMetric(PM_LayoutVerticalSpacing) + - pixelMetric(PM_FocusFrameVMargin)); const int frameWidthReduction = - qMin(0, pixelMetric(QStyle::PM_LayoutHorizontalSpacing) - - pixelMetric(QStyle::PM_FocusFrameHMargin)); + qMin(0, pixelMetric(PM_LayoutHorizontalSpacing) + - pixelMetric(PM_FocusFrameHMargin)); const int rounding = - qMin(pixelMetric(QStyle::PM_FocusFrameVMargin), - pixelMetric(QStyle::PM_LayoutVerticalSpacing)); + qMin(pixelMetric(PM_FocusFrameVMargin), + pixelMetric(PM_LayoutVerticalSpacing)); const QRect frameRect = option->rect.adjusted(-frameWidthReduction, -frameHeightReduction, frameWidthReduction, frameHeightReduction); @@ -2037,7 +2023,10 @@ 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); + QS60StylePrivate::drawSkinElement( + QS60StylePrivate::isWidgetPressed(widget) ? + QS60StylePrivate::SE_ListItemPressed : + QS60StylePrivate::SE_ListHighlight, painter, option->rect, flags); else commonStyleDraws = true; } @@ -2257,6 +2246,57 @@ break; #ifndef QT_NO_ITEMVIEWS case PE_PanelItemViewItem: + if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast(option)) { + const bool isSelected = (vopt->state & State_Selected); + const bool hasFocus = (vopt->state & State_HasFocus); + const bool isPressed = QS60StylePrivate::isWidgetPressed(widget); + + if (option->palette.highlight().color() == QS60StylePrivate::themePalette()->highlight().color()) { + QRect highlightRect = vopt->rect.adjusted(1,1,-1,-1); + const QAbstractItemView *itemView = qobject_cast(widget); + QAbstractItemView::SelectionBehavior selectionBehavior = + itemView ? itemView->selectionBehavior() : QAbstractItemView::SelectItems; + // Set the draw area for highlights (focus, select rect or pressed rect) + if (hasFocus || isSelected || isPressed) { + if (selectionBehavior != QAbstractItemView::SelectItems) { + // set highlight rect so that it is continuous from cell to cell, yet sligthly + // smaller than cell rect + int xBeginning = 0, yBeginning = 0, xEnd = 0, yEnd = 0; + if (selectionBehavior == QAbstractItemView::SelectRows) { + yBeginning = 1; yEnd = -1; + if (vopt->viewItemPosition == QStyleOptionViewItemV4::Beginning) + xBeginning = 1; + else if (vopt->viewItemPosition == QStyleOptionViewItemV4::End) + xEnd = -1; + } else if (selectionBehavior == QAbstractItemView::SelectColumns) { + xBeginning = 1; xEnd = -1; + if (vopt->viewItemPosition == QStyleOptionViewItemV4::Beginning) + yBeginning = 1; + else if (vopt->viewItemPosition == QStyleOptionViewItemV4::End) + yEnd = -1; + } + highlightRect = option->rect.adjusted(xBeginning, yBeginning, xEnd, yEnd); + } + } + bool tableView = false; + if (itemView && qobject_cast(widget)) + tableView = true; + + QS60StylePrivate::SkinElements element; + QRect elementRect = option->rect; + + //draw item is drawn as pressed, if it already has focus. + if (isPressed && (hasFocus || isSelected)) { + element = tableView ? QS60StylePrivate::SE_TableItemPressed : QS60StylePrivate::SE_ListItemPressed; + } else if (hasFocus || (isSelected && selectionBehavior != QAbstractItemView::SelectItems)) { + element = QS60StylePrivate::SE_ListHighlight; + elementRect = highlightRect; + } + QS60StylePrivate::drawSkinElement(element, painter, elementRect, flags); + } else { + QCommonStyle::drawPrimitive(element, option, painter, widget); + } + } break; #endif //QT_NO_ITEMVIEWS @@ -2433,7 +2473,7 @@ const int contentHeight = qMax(qMax(iconHeight, decoratorHeight) + pixelMetric(PM_ButtonMargin), textHeight + 2*pixelMetric(PM_ButtonMargin)); - sz.setHeight(contentHeight); + sz.setHeight(qMax(sz.height(), contentHeight)); sz += QSize(2 * pixelMetric(PM_ButtonMargin), 0); } break; @@ -2448,6 +2488,7 @@ sz.setHeight(naviPaneSize.height()); } break; + case CT_MenuItem: case CT_ItemViewItem: sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget); if (QS60StylePrivate::isTouchSupported()) @@ -2814,7 +2855,7 @@ const int tabOverlapNoBorder = QS60StylePrivate::pixelMetric(PM_TabBarTabOverlap); const int tabOverlap = - tabOverlapNoBorder-QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth); + tabOverlapNoBorder - QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth); const QTabWidget *tab = qobject_cast(widget); int gain = (tab) ? tabOverlap * tab->count() : 0; switch (twf->shape) { @@ -2880,7 +2921,7 @@ ret = QRect(); } else { if (menuItem->direction == Qt::RightToLeft) - ret.translate(ret.width()-indicatorWidth, 0); + ret.translate(ret.width() - indicatorWidth, 0); ret.setWidth(indicatorWidth); } } else { @@ -3067,8 +3108,11 @@ void QS60Style::polish(QApplication *application) { Q_D(QS60Style); + QCommonStyle::polish(qApp); d->m_originalPalette = application->palette(); d->setThemePalette(application); + if (QS60StylePrivate::isTouchSupported()) + qApp->installEventFilter(this); } /*! @@ -3077,10 +3121,14 @@ void QS60Style::unpolish(QApplication *application) { Q_UNUSED(application) + Q_D(QS60Style); + QCommonStyle::unpolish(qApp); const QPalette newPalette = QApplication::style()->standardPalette(); QApplication::setPalette(newPalette); QApplicationPrivate::setSystemPalette(d->m_originalPalette); + if (QS60StylePrivate::isTouchSupported()) + qApp->removeEventFilter(this); } /*! @@ -3108,6 +3156,12 @@ #ifdef QT_KEYPAD_NAVIGATION case QEvent::FocusIn: if (QWidget *focusWidget = QApplication::focusWidget()) { + + // Menus and combobox popups do not draw focus frame around them + if (qobject_cast(focusWidget) || + qobject_cast(focusWidget)) + break; + if (!d->m_focusFrame) d->m_focusFrame = new QFocusFrame(focusWidget); d->m_focusFrame->setWidget(focusWidget); @@ -3227,9 +3281,40 @@ */ bool QS60Style::eventFilter(QObject *object, QEvent *event) { + Q_D(QS60Style); + switch(event->type()) { + case QEvent::MouseButtonPress: { + QWidget *w = QApplication::widgetAt(QCursor::pos()); + if (w) { + QWidget *focusW = w->focusProxy(); + if (qobject_cast(focusW) || + qobject_cast(focusW) || + qobject_cast(focusW)) + d->m_pressedWidget = focusW; + else if (qobject_cast(w)|| + qobject_cast(w) || + qobject_cast(w)) + d->m_pressedWidget = w; + + if ( d->m_pressedWidget) + d->m_pressedWidget->update(); + } + break; + } + case QEvent::MouseButtonRelease: { + const QWidget *w = QApplication::widgetAt(QCursor::pos()); + if (w && d->m_pressedWidget) { + d->m_pressedWidget->update(); + d->m_pressedWidget = 0; + } + break; + } + default: + break; + } + #ifdef Q_WS_S60 #ifndef QT_NO_PROGRESSBAR - Q_D(QS60Style); switch(event->type()) { case QEvent::StyleChange: case QEvent::Show: @@ -3242,15 +3327,17 @@ break; case QEvent::Destroy: case QEvent::Hide: - d->stopAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim); - d->m_bars.removeAll(reinterpret_cast(object)); + if (QProgressBar *bar = reinterpret_cast(object)) { + d->stopAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim); + d->m_bars.removeAll(bar); + } break; default: break; } #endif // QT_NO_PROGRESSBAR #endif // Q_WS_S60 - return QStyle::eventFilter(object, event); + return QCommonStyle::eventFilter(object, event); } /*!