summaryrefslogtreecommitdiffstats
path: root/src/gui/widgets
diff options
context:
space:
mode:
authorAlessandro Portale <aportale@trolltech.com>2009-09-19 11:37:38 (GMT)
committerAlessandro Portale <aportale@trolltech.com>2009-09-19 11:37:38 (GMT)
commitcd48ed92670a0d086589b202364f38f14e7221c9 (patch)
treea3e9d51e75822a1380699d7cd5fb87ee1522239d /src/gui/widgets
parent3581668cd0ffbe47a05ce7467f8d89b8c9bb6101 (diff)
downloadQt-cd48ed92670a0d086589b202364f38f14e7221c9.zip
Qt-cd48ed92670a0d086589b202364f38f14e7221c9.tar.gz
Qt-cd48ed92670a0d086589b202364f38f14e7221c9.tar.bz2
Making Keypad Navigation more usable
All changes of this commit are #ifdef'ed in QT_KEYPAD_NAVIGATION. Most desktop Qts won't notice any change. Navigating between QWidgets was not alwys a pleasure on keypad devices. This commit fixes the navigation behavior for some widgets, mostly itemviews. Furthermore, it adds a 'directional' navigation mode. Until now, the existing keypad navigation used the tab order do go back and forth between widgets. The new mode is supposed to provide a more intuitive navigation. It is the new default mode on Symbian. Screens (and their resolutions) become bigger, and also low resolution screens can be used in landscape mode. That's why the directional mode was requested. Another popular request was to put some more convenience into QSlider: If a (horizontal) slider has focus and the user presses left/right, the value of the slider may directing change without being selected (edit mode). This commit also adds the manual test 'keypadnavigation'. Reviewed-by: Shane Kearns
Diffstat (limited to 'src/gui/widgets')
-rw-r--r--src/gui/widgets/qabstractbutton.cpp5
-rw-r--r--src/gui/widgets/qabstractslider.cpp69
-rw-r--r--src/gui/widgets/qmenu.cpp5
-rw-r--r--src/gui/widgets/qplaintextedit.cpp9
4 files changed, 78 insertions, 10 deletions
diff --git a/src/gui/widgets/qabstractbutton.cpp b/src/gui/widgets/qabstractbutton.cpp
index d2f4baf..cb46791 100644
--- a/src/gui/widgets/qabstractbutton.cpp
+++ b/src/gui/widgets/qabstractbutton.cpp
@@ -1172,7 +1172,10 @@ void QAbstractButton::keyPressEvent(QKeyEvent *e)
case Qt::Key_Right:
case Qt::Key_Down:
#ifdef QT_KEYPAD_NAVIGATION
- if (QApplication::keypadNavigationEnabled() && (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right)) {
+ if ((QApplication::keypadNavigationEnabled()
+ && (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right))
+ || (!QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional
+ || (e->key() == Qt::Key_Up || e->key() == Qt::Key_Down))) {
e->ignore();
return;
}
diff --git a/src/gui/widgets/qabstractslider.cpp b/src/gui/widgets/qabstractslider.cpp
index 34fe340..a50c105 100644
--- a/src/gui/widgets/qabstractslider.cpp
+++ b/src/gui/widgets/qabstractslider.cpp
@@ -47,6 +47,9 @@
#ifndef QT_NO_ACCESSIBILITY
#include "qaccessible.h"
#endif
+#ifdef QT_KEYPAD_NAVIGATION
+#include "qtabwidget.h" // Needed in inTabWidget()
+#endif // QT_KEYPAD_NAVIGATION
#include <limits.h>
QT_BEGIN_NAMESPACE
@@ -724,6 +727,45 @@ void QAbstractSlider::wheelEvent(QWheelEvent * e)
}
}
#endif
+#ifdef QT_KEYPAD_NAVIGATION
+/*!
+ \internal
+
+ Tells us if it there is currently a reachable widget by keypad navigation in
+ a certain \a orientation.
+ If no navigation is possible, occuring key events in that \a orientation may
+ be used to interact with the value in the focussed widget, even though it
+ currently has not the editFocus.
+
+ \sa QWidgetPrivate::widgetInNavigationDirection(), QWidget::hasEditFocus()
+*/
+inline static bool canKeypadNavigate(Qt::Orientation orientation)
+{
+ return orientation == Qt::Horizontal?
+ (QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionEast)
+ || QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionWest))
+ :(QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionNorth)
+ || QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionSouth));
+}
+/*!
+ \internal
+
+ Checks, if the \a widget is inside a QTabWidget. If is is inside
+ one, left/right key events will be used to switch between tabs in keypad
+ navigation. If there is no QTabWidget, the horizontal key events can be used to
+ interact with the value in the focussed widget, even though it currently has
+ not the editFocus.
+
+ \sa QWidget::hasEditFocus()
+*/
+inline static bool inTabWidget(QWidget *widget)
+{
+ for (QWidget *tabWidget = widget; tabWidget; tabWidget = tabWidget->parentWidget())
+ if (qobject_cast<const QTabWidget*>(tabWidget))
+ return true;
+ return false;
+}
+#endif // QT_KEYPAD_NAVIGATION
/*!
\reimp
*/
@@ -751,7 +793,13 @@ void QAbstractSlider::keyPressEvent(QKeyEvent *ev)
// It seems we need to use invertedAppearance for Left and right, otherwise, things look weird.
case Qt::Key_Left:
#ifdef QT_KEYPAD_NAVIGATION
- if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) {
+ // In QApplication::KeypadNavigationDirectional, we want to change the slider
+ // value if there is no left/right navigation possible and if this slider is not
+ // inside a tab widget.
+ if (QApplication::keypadNavigationEnabled()
+ && (!hasEditFocus() && QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
+ || d->orientation == Qt::Vertical
+ || !hasEditFocus() && (canKeypadNavigate(Qt::Horizontal) || inTabWidget(this)))) {
ev->ignore();
return;
}
@@ -766,7 +814,11 @@ void QAbstractSlider::keyPressEvent(QKeyEvent *ev)
break;
case Qt::Key_Right:
#ifdef QT_KEYPAD_NAVIGATION
- if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) {
+ // Same logic as in Qt::Key_Left
+ if (QApplication::keypadNavigationEnabled()
+ && (!hasEditFocus() && QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
+ || d->orientation == Qt::Vertical
+ || !hasEditFocus() && (canKeypadNavigate(Qt::Horizontal) || inTabWidget(this)))) {
ev->ignore();
return;
}
@@ -781,7 +833,12 @@ void QAbstractSlider::keyPressEvent(QKeyEvent *ev)
break;
case Qt::Key_Up:
#ifdef QT_KEYPAD_NAVIGATION
- if (QApplication::keypadNavigationEnabled()) {
+ // In QApplication::KeypadNavigationDirectional, we want to change the slider
+ // value if there is no up/down navigation possible.
+ if (QApplication::keypadNavigationEnabled()
+ && (QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
+ || d->orientation == Qt::Horizontal
+ || !hasEditFocus() && canKeypadNavigate(Qt::Vertical))) {
ev->ignore();
break;
}
@@ -790,7 +847,11 @@ void QAbstractSlider::keyPressEvent(QKeyEvent *ev)
break;
case Qt::Key_Down:
#ifdef QT_KEYPAD_NAVIGATION
- if (QApplication::keypadNavigationEnabled()) {
+ // Same logic as in Qt::Key_Up
+ if (QApplication::keypadNavigationEnabled()
+ && (QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
+ || d->orientation == Qt::Horizontal
+ || !hasEditFocus() && canKeypadNavigate(Qt::Vertical))) {
ev->ignore();
break;
}
diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp
index d971ac2..925be02 100644
--- a/src/gui/widgets/qmenu.cpp
+++ b/src/gui/widgets/qmenu.cpp
@@ -570,11 +570,6 @@ void QMenuPrivate::setCurrentAction(QAction *action, int popup, SelectionReason
// Since the menu is a pop-up, it uses the popup reason.
if (!q->hasFocus()) {
q->setFocus(Qt::PopupFocusReason);
-#ifdef QT_KEYPAD_NAVIGATION
- // TODO: aportale, remove KEYPAD_NAVIGATION_HACK when softkey stack
- // handles focus related and user related actions separately...
- QActionToKeyEventMapper::addSoftKey(QAction::CancelSoftKey, Qt::Key_Back, q);
-#endif
}
}
}
diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp
index fda063a..d519bfe 100644
--- a/src/gui/widgets/qplaintextedit.cpp
+++ b/src/gui/widgets/qplaintextedit.cpp
@@ -1639,6 +1639,15 @@ void QPlainTextEdit::keyPressEvent(QKeyEvent *e)
return;
}
break;
+ case Qt::Key_Left:
+ case Qt::Key_Right:
+ if (QApplication::keypadNavigationEnabled()
+ && QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional) {
+ // Same as for Key_Up and Key_Down.
+ e->ignore();
+ return;
+ }
+ break;
case Qt::Key_Back:
if (!e->isAutoRepeat()) {
if (QApplication::keypadNavigationEnabled()) {