From 0673dd4ff18bbc8d530a4dd08e394cc04c6711ca Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Thu, 8 Jun 2017 07:12:53 +0200 Subject: QQuickMenu: add a little delay for opening sub-menus on hover This improves the usability on desktop. When a menu has multiple sub- menu items, they don't all trigger a sub-menu (and close immediately) while moving mouse over the items. Change-Id: Ie4c9e409da8d6877e35506bffb94ed57f5985dcd Reviewed-by: Mitch Curtis --- src/quicktemplates2/qquickmenu.cpp | 33 ++++++++++++++++++++++++++++++++- src/quicktemplates2/qquickmenu_p.h | 2 ++ src/quicktemplates2/qquickmenu_p_p.h | 4 ++++ 3 files changed, 38 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/quicktemplates2/qquickmenu.cpp b/src/quicktemplates2/qquickmenu.cpp index 37d314a8..1b2ed841 100644 --- a/src/quicktemplates2/qquickmenu.cpp +++ b/src/quicktemplates2/qquickmenu.cpp @@ -59,6 +59,9 @@ QT_BEGIN_NAMESPACE +// copied from qfusionstyle.cpp +static const int SUBMENU_DELAY = 225; + /*! \qmltype Menu \inherits Popup @@ -183,6 +186,7 @@ static bool shouldCascade() QQuickMenuPrivate::QQuickMenuPrivate() : cascade(shouldCascade()), + hoverTimer(0), overlap(0), contentItem(nullptr), contentModel(nullptr), @@ -371,7 +375,7 @@ void QQuickMenuPrivate::onItemHovered() if (currentItem) { QQuickMenu *subMenu = currentItem->menu(); if (subMenu && subMenu->cascade()) - openSubMenu(currentItem, false); + startHoverTimer(); } } } @@ -468,6 +472,23 @@ void QQuickMenuPrivate::closeSubMenu(QQuickMenu *subMenu) } } +void QQuickMenuPrivate::startHoverTimer() +{ + Q_Q(QQuickMenu); + stopHoverTimer(); + hoverTimer = q->startTimer(SUBMENU_DELAY); +} + +void QQuickMenuPrivate::stopHoverTimer() +{ + Q_Q(QQuickMenu); + if (!hoverTimer) + return; + + q->killTimer(hoverTimer); + hoverTimer = 0; +} + int QQuickMenuPrivate::currentIndex() const { QVariant index = contentItem->property("currentIndex"); @@ -483,6 +504,7 @@ void QQuickMenuPrivate::setCurrentIndex(int index) QQuickMenuItem *newCurrentItem = contentItem->property("currentItem").value(); if (currentItem != newCurrentItem) { + stopHoverTimer(); if (currentItem) currentItem->setHighlighted(false); if (newCurrentItem) @@ -1013,6 +1035,15 @@ void QQuickMenu::keyReleaseEvent(QKeyEvent *event) item->forceActiveFocus(); } +void QQuickMenu::timerEvent(QTimerEvent *event) +{ + Q_D(QQuickMenu); + if (event->timerId() == d->hoverTimer) { + d->openSubMenu(d->currentItem, false); + d->stopHoverTimer(); + } +} + QFont QQuickMenu::defaultFont() const { return QQuickControlPrivate::themeFont(QPlatformTheme::MenuFont); diff --git a/src/quicktemplates2/qquickmenu_p.h b/src/quicktemplates2/qquickmenu_p.h index f7f56d45..356798b9 100644 --- a/src/quicktemplates2/qquickmenu_p.h +++ b/src/quicktemplates2/qquickmenu_p.h @@ -111,6 +111,8 @@ Q_SIGNALS: Q_REVISION(3) void delegateChanged(); protected: + void timerEvent(QTimerEvent *event) override; + QFont defaultFont() const override; QPalette defaultPalette() const override; diff --git a/src/quicktemplates2/qquickmenu_p_p.h b/src/quicktemplates2/qquickmenu_p_p.h index 675f1d93..5887d4e5 100644 --- a/src/quicktemplates2/qquickmenu_p_p.h +++ b/src/quicktemplates2/qquickmenu_p_p.h @@ -102,6 +102,9 @@ public: void openSubMenu(QQuickMenuItem *item, bool activate); void closeSubMenu(QQuickMenu *subMenu); + void startHoverTimer(); + void stopHoverTimer(); + int currentIndex() const; void setCurrentIndex(int index); @@ -111,6 +114,7 @@ public: static void contentData_clear(QQmlListProperty *prop); bool cascade; + int hoverTimer; qreal overlap; QPointer parentMenu; QPointer currentItem; -- cgit v1.2.3