diff options
author | Alessandro Portale <alessandro.portale@nokia.com> | 2009-08-28 15:47:11 (GMT) |
---|---|---|
committer | Alessandro Portale <alessandro.portale@nokia.com> | 2009-08-28 15:56:28 (GMT) |
commit | 7621eec3fb023c7e477080b57c0aba858627091b (patch) | |
tree | 4f1eecd09269c38841d83122233f7dd5ef9e969f | |
parent | 15144fab1010194b078c34157e8d208cfb625e88 (diff) | |
download | Qt-7621eec3fb023c7e477080b57c0aba858627091b.zip Qt-7621eec3fb023c7e477080b57c0aba858627091b.tar.gz Qt-7621eec3fb023c7e477080b57c0aba858627091b.tar.bz2 |
Using QFocusFrame to visualize the focus.
When using the keypad navigation, the focus state of a widget is
supposed to be well visible. So it makes much sense to use QFocusFrame,
which is able to paint a focus marker _around_ the widget.
This change should fix the issue that with some S60 themes, the focus
was invisible.
Also, a lot of code is removed by this change.
Task-number: 256470
Reviewed-by: Sami Merila
modified: src/gui/styles/qs60style.cpp
modified: src/gui/styles/qs60style.h
modified: src/gui/styles/qs60style_p.h
-rw-r--r-- | src/gui/styles/qs60style.cpp | 190 | ||||
-rw-r--r-- | src/gui/styles/qs60style.h | 2 | ||||
-rw-r--r-- | src/gui/styles/qs60style_p.h | 6 |
3 files changed, 80 insertions, 118 deletions
diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index b05a1e9..12d4948 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -67,6 +67,7 @@ #include "qtoolbar.h" #include "qtoolbutton.h" #include "qtreeview.h" +#include "qfocusframe.h" #include "private/qtoolbarextension_p.h" #include "private/qcombobox_p.h" @@ -86,6 +87,8 @@ const QS60StylePrivate::SkinElementFlags QS60StylePrivate::KDefaultSkinElementFl static const QByteArray propertyKeyLayouts = "layouts"; static const QByteArray propertyKeyCurrentlayout = "currentlayout"; +static const qreal goldenRatio = 1.618; + const layoutHeader QS60StylePrivate::m_layoutHeaders[] = { // *** generated layout data *** {240,320,1,14,true,"QVGA Landscape Mirrored"}, @@ -508,11 +511,6 @@ void QS60StylePrivate::deleteBackground() } } -int QS60StylePrivate::focusRectPenWidth() -{ - return pixelMetric(QS60Style::PM_DefaultFrameWidth); -} - void QS60StylePrivate::setCurrentLayout(int index) { m_pmPointer = data[index]; @@ -950,13 +948,6 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom const QS60StylePrivate::SkinElements handleElement = horizontal ? QS60StylePrivate::SE_SliderHandleHorizontal : QS60StylePrivate::SE_SliderHandleVertical; QS60StylePrivate::drawSkinElement(handleElement, painter, sliderHandle, flags); - - if (optionSlider->state & State_HasFocus) { - QStyleOptionFocusRect fropt; - fropt.QStyleOption::operator=(*optionSlider); - fropt.rect = subElementRect(SE_SliderFocusRect, optionSlider, widget); - drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget); - } } break; #endif // QT_NO_SLIDER @@ -991,17 +982,6 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom drawPrimitive(PE_IndicatorSpinDown, &buttonOption, painter, widget); painter->restore(); } - - if (cmb->subControls & SC_ComboBoxEditField) { - if (cmb->state & State_HasFocus && !cmb->editable) { - QStyleOptionFocusRect focus; - focus.QStyleOption::operator=(*cmb); - focus.rect = cmbxEditField; - focus.state |= State_FocusAtBorder; - focus.backgroundColor = cmb->palette.highlight().color(); - drawPrimitive(PE_FrameFocusRect, &focus, painter, widget); - } - } } break; #endif // QT_NO_COMBOBOX @@ -1079,13 +1059,6 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom } } } - if (toolBtn->state & State_HasFocus) { - QStyleOptionFocusRect fr; - fr.QStyleOption::operator=(*toolBtn); - const int frameWidth = pixelMetric(PM_DefaultFrameWidth, option, widget); - fr.rect.adjust(frameWidth, frameWidth, -frameWidth, -frameWidth); - drawPrimitive(PE_FrameFocusRect, &fr, painter, widget); - } if (toolBtn->features & QStyleOptionToolButton::Arrow) { QStyle::PrimitiveElement pe; @@ -1209,13 +1182,6 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom groupBox->palette, groupBox->state & State_Enabled, groupBox->text, textColor.isValid() ? QPalette::NoRole : QPalette::WindowText); painter->restore(); - - if (groupBox->state & State_HasFocus) { - QStyleOptionFocusRect fropt; - fropt.QStyleOption::operator=(*groupBox); - fropt.rect = textRect; - drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget); - } } // Draw checkbox @@ -1249,12 +1215,6 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, subopt.rect = subElementRect(SE_PushButtonContents, btn, widget); drawControl(CE_PushButtonLabel, &subopt, painter, widget); - if (btn->state & State_HasFocus) { - QStyleOptionFocusRect fropt; - fropt.QStyleOption::operator=(*btn); - fropt.rect = subElementRect(SE_PushButtonFocusRect, btn, widget); - drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget); - } } break; case CE_PushButtonBevel: @@ -1612,18 +1572,6 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, if (verticalTabs) painter->restore(); - if (optionTab.state & State_HasFocus) { - const int OFFSET = 1 + pixelMetric(PM_DefaultFrameWidth); - const int leftBorder = optionTab.rect.left(); - const int rightBorder = optionTab.rect.right() - 1; - - QStyleOptionFocusRect fropt; - fropt.QStyleOption::operator=(*tab); - fropt.rect.setRect(leftBorder + 1 + OFFSET, optionTab.rect.y() + OFFSET, - rightBorder - leftBorder - 2*OFFSET, optionTab.rect.height() - 2*OFFSET); - drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget); - } - painter->restore(); } break; @@ -1875,11 +1823,48 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, } else if (qobject_cast<const QFrame *>(widget)) { QCommonStyle::drawControl(element, option, painter, widget); } - if (option->state & State_HasFocus) - drawPrimitive(PE_FrameFocusRect, option, painter, widget); break; 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<const QFocusFrame*>(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. +#else + const qreal opacity = 0.5; +#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; + + painter->save(); + painter->setRenderHint(QPainter::Antialiasing); + painter->setOpacity(opacity); + painter->setPen(QPen(option->palette.color(QPalette::Highlight), penWidth)); + painter->drawRoundedRect(adjustedRect, roundRectRadius, roundRectRadius); + painter->restore(); + } + break; default: QCommonStyle::drawControl(element, option, painter, widget); } @@ -1901,9 +1886,6 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti #endif QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_FrameLineEdit, painter, option->rect, flags); - - if (lineEdit->state & State_HasFocus) - drawPrimitive(PE_FrameFocusRect, lineEdit, painter, widget); } break; #endif // QT_NO_LINEEDIT @@ -2030,50 +2012,6 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti #endif //QT_NO_COMBOBOX break; #endif //QT_NO_SPINBOX - case PE_FrameFocusRect: -// Calendar widget and combox both do not use styled itemDelegate - if (widget && !(false -#ifndef QT_NO_CALENDARWIDGET - || qobject_cast<const QCalendarWidget *>(widget->parent()) -#endif //QT_NO_CALENDARWIDGET -#ifndef QT_NO_COMBOBOX - || qobject_cast<const QComboBoxListView *>(widget) -#endif //QT_NO_COMBOBOX - )) { - // no focus selection for touch - if (option->state & State_HasFocus && !QS60StylePrivate::isTouchSupported()) { - painter->save(); - const int penWidth = QS60StylePrivate::focusRectPenWidth(); -#ifdef QT_KEYPAD_NAVIGATION - const Qt::PenStyle penStyle = widget->hasEditFocus() ? Qt::SolidLine :Qt::DashLine; - const qreal opacity = widget->hasEditFocus() ? 0.6 : 0.4; -#else - const Qt::PenStyle penStyle = Qt::SolidLine; - const qreal opacity = 0.5; -#endif - painter->setRenderHint(QPainter::Antialiasing); - painter->setOpacity(opacity); - // 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; - // Also we try to stay inside the option->rect, with penWidth > 1. Therefore these +1/-1 - const QRectF adjustedRect = QRectF(option->rect).adjusted( - rectAdjustment + penWidth - 1, - rectAdjustment + penWidth - 1, - -rectAdjustment - penWidth + 1, - -rectAdjustment - penWidth + 1); - const qreal roundRectRadius = penWidth * 1.5; -#ifdef QT_KEYPAD_NAVIGATION - if (penStyle != Qt::SolidLine) { - painter->setPen(QPen(option->palette.color(QPalette::HighlightedText), penWidth, Qt::SolidLine)); - painter->drawRoundedRect(adjustedRect, roundRectRadius, roundRectRadius); - } -#endif - painter->setPen(QPen((option->palette.color(QPalette::Text), penWidth, penStyle))); - painter->drawRoundedRect(adjustedRect, roundRectRadius, roundRectRadius); - painter->restore(); - } - } - break; case PE_Widget: if (QS60StylePrivate::drawsOwnThemeBackground(widget) #ifndef QT_NO_COMBOBOX @@ -2118,8 +2056,6 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti Q_ASSERT(false); break; case PE_Frame: - if (const QStyleOptionFrameV3 *frame = qstyleoption_cast<const QStyleOptionFrameV3 *>(option)) - drawPrimitive(PE_FrameFocusRect, frame, painter, widget); break; #ifndef QT_NO_ITEMVIEWS case PE_PanelItemViewItem: @@ -2668,16 +2604,6 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con } ret = visualRect(opt->direction, opt->rect, ret); break; - case SE_FrameContents: - if (QS60StylePrivate::isTouchSupported()) { - return QCommonStyle::subElementRect(element, opt, widget); - } else if (const QStyleOptionFrameV2 *f = qstyleoption_cast<const QStyleOptionFrameV2 *>(opt)) { - // We shrink the frame contents by focusFrameWidth, so that we can draw the frame around it in keypad navigation mode. - const int frameWidth = QS60StylePrivate::focusRectPenWidth(); - ret = opt->rect.adjusted(frameWidth, frameWidth, -frameWidth, -frameWidth); - ret = visualRect(opt->direction, opt->rect, ret); - } - break; default: ret = QCommonStyle::subElementRect(element, opt, widget); } @@ -2778,6 +2704,38 @@ QVariant QS60Style::styleProperty(const char *name) const return d->styleProperty_specific(name); } +bool QS60Style::event(QEvent *e) +{ +#ifdef QT_KEYPAD_NAVIGATION + if (QS60StylePrivate::isTouchSupported()) + return false; + Q_D(QS60Style); + switch (e->type()) { + case QEvent::FocusIn: + if (QWidget *focusWidget = QApplication::focusWidget()) { + if (!d->m_focusFrame) + d->m_focusFrame = new QFocusFrame(focusWidget); + d->m_focusFrame->setWidget(focusWidget); + } else if (d->m_focusFrame) { + d->m_focusFrame->setWidget(0); + } + break; + case QEvent::FocusOut: + if (d->m_focusFrame) + d->m_focusFrame->setWidget(0); + break; + case QEvent::EnterEditFocus: + case QEvent::LeaveEditFocus: + if (d->m_focusFrame) + d->m_focusFrame->update(); + break; + default: + break; + } +#endif + return false; +} + QIcon QS60Style::standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget) const { diff --git a/src/gui/styles/qs60style.h b/src/gui/styles/qs60style.h index a03803b..c01c40a 100644 --- a/src/gui/styles/qs60style.h +++ b/src/gui/styles/qs60style.h @@ -80,6 +80,8 @@ public: void setStyleProperty(const char *name, const QVariant &value); QVariant styleProperty(const char *name) const; + bool event(QEvent *e); + #ifndef Q_WS_S60 static QStringList partKeys(); static QStringList colorListKeys(); diff --git a/src/gui/styles/qs60style_p.h b/src/gui/styles/qs60style_p.h index 2e661c0..ed0abfa 100644 --- a/src/gui/styles/qs60style_p.h +++ b/src/gui/styles/qs60style_p.h @@ -292,6 +292,8 @@ public: }; }; +class QFocusFrame; + // Private class #ifdef Q_OS_SYMBIAN NONSHARABLE_CLASS (QS60StylePrivate) @@ -430,8 +432,6 @@ public: //access to theme palette static QPalette* themePalette(); - static int focusRectPenWidth(); - static const layoutHeader m_layoutHeaders[]; static const short data[][MAX_PIXELMETRICS]; @@ -499,6 +499,8 @@ private: // defined theme palette static QPalette *m_themePalette; QPalette m_originalPalette; + + QPointer<QFocusFrame> m_focusFrame; }; QT_END_NAMESPACE |