summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlessandro Portale <alessandro.portale@nokia.com>2009-08-28 15:47:11 (GMT)
committerAlessandro Portale <alessandro.portale@nokia.com>2009-08-28 15:56:28 (GMT)
commit7621eec3fb023c7e477080b57c0aba858627091b (patch)
tree4f1eecd09269c38841d83122233f7dd5ef9e969f
parent15144fab1010194b078c34157e8d208cfb625e88 (diff)
downloadQt-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.cpp190
-rw-r--r--src/gui/styles/qs60style.h2
-rw-r--r--src/gui/styles/qs60style_p.h6
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