diff options
author | Gabriel de Dietrich <gabriel.dedietrich@digia.com> | 2013-02-22 21:15:52 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-02-25 13:39:38 +0100 |
commit | 4cc6b22c51a5b42e8a19c7b30475dacb537e02a1 (patch) | |
tree | 130bc20c64f84d56687eb6245bd875783b98c36c /src/controls/Menu.qml | |
parent | 28b73e87fdaf9738f14c36e62940215658ec01ac (diff) | |
download | qtquickcontrols-4cc6b22c51a5b42e8a19c7b30475dacb537e02a1.tar.gz |
Menu: Enable "click-select-release" behavior
Some limitations in MouseArea force us to abandon the "one mouse area
per menu item" implementation in favor of a menu-wide mouse area,
where we track the position changes to highlight the menu item under
the mouse cursor. This makes possible updating the highlighted menu
item while keeping the mouse pressed.
Also, we need to emit an extra mouse press event, from the menu popup
window, so that the menu mouse area will receive any mouse release
event the user may have triggered. This is because the initial mouse
press event popping up the menu was made in another window, and
MouseArea would only emit 'released' signals if the released button
was already pressed.
Change-Id: Id10dd61fcf9e38ef3d34a61b7172301802e9646c
Reviewed-by: J-P Nurmi <jpnurmi@digia.com>
Diffstat (limited to 'src/controls/Menu.qml')
-rw-r--r-- | src/controls/Menu.qml | 72 |
1 files changed, 32 insertions, 40 deletions
diff --git a/src/controls/Menu.qml b/src/controls/Menu.qml index 1d2ca474..270c7869 100644 --- a/src/controls/Menu.qml +++ b/src/controls/Menu.qml @@ -94,6 +94,8 @@ MenuPrivate { property var menuBar: null //! internal property int currentIndex: -1 + //! internal + onMenuClosed: currentIndex = -1 //! internal menuContentItem: Loader { @@ -166,7 +168,7 @@ MenuPrivate { Keys.onRightPressed: { var item = itemsRepeater.itemAt(root.currentIndex) if (item && item.hasSubmenu) { - item.menuItem.showPopup(menuFrameLoader.subMenuXPos, 0, -1, item) + item.showSubMenu() item.menuItem.currentIndex = 0 } } @@ -195,8 +197,28 @@ MenuPrivate { id: menuMouseArea anchors.fill: parent hoverEnabled: true - - onExited: root.currentIndex = -1 // TODO Test for any submenu open + acceptedButtons: Qt.AllButtons + + onPositionChanged: updateCurrentItem(mouse) + onReleased: menuFrameLoader.triggerAndDismiss() + + property Item currentItem: null + + function updateCurrentItem(mouse) { + var pos = mapToItem(column, mouse.x, mouse.y) + if (!currentItem || !currentItem.contains(Qt.point(pos.x - currentItem.x, pos.y - currentItem.y))) { + if (currentItem && !pressed && currentItem.hasSubmenu) + currentItem.closeSubMenu() + currentItem = column.childAt(pos.x, pos.y) + if (currentItem) { + root.currentIndex = currentItem.menuItemIndex + if (currentItem.hasSubmenu && !currentItem.menuItem.popupVisible) + currentItem.showSubMenu() + } else { + root.currentIndex = -1 + } + } + } // Each menu item has its own mouse area, and for events to be // propagated to the menu mouse area, they need to be embedded. @@ -211,63 +233,33 @@ MenuPrivate { id: menuItemLoader property var menuItem: modelData - property int contentWidth: column.width - property int contentHeight: column.height property bool isSeparator: menuItem ? !menuItem.hasOwnProperty("text") : false property bool hasSubmenu: menuItem ? !!menuItem["menuItems"] : false property bool selected: !isSeparator && root.currentIndex === index + property int menuItemIndex: index + sourceComponent: menuFrameLoader.menuItemStyle enabled: !isSeparator && !!menuItem && menuItem.enabled - MouseArea { - id: itemMouseArea - width: menuFrameLoader.width - height: parent.height - y: menuItemLoader.item ? menuItemLoader.item.y : 0 // Adjust mouse area for style offset - hoverEnabled: true - - onClicked: { - if (hasSubmenu) - menuItem.closeMenu() - menuFrameLoader.triggerAndDismiss() - } - - onEntered: { - if (menuItemLoader.hasSubmenu && !menuItem.popupVisible) - openMenuTimer.start() - } - - onExited: { - if (!pressed && menuItemLoader.hasSubmenu) - closeMenuTimer.start() - } - - onPositionChanged: root.currentIndex = index - - Connections { - target: menuMouseArea - onEntered: { - if (!itemMouseArea.containsMouse && menuItemLoader.hasSubmenu) - closeMenuTimer.start() - } - } - } + function showSubMenu() { openMenuTimer.start() } Timer { id: openMenuTimer interval: 50 onTriggered: { - if (itemMouseArea.containsMouse) + if (root.currentIndex === menuItemIndex) menuItem.showPopup(menuFrameLoader.subMenuXPos, 0, -1, menuItemLoader) } } + function closeSubMenu() { closeMenuTimer.start() } + Timer { id: closeMenuTimer interval: 1 onTriggered: { - if (menuMouseArea.containsMouse && !itemMouseArea.pressed && !itemMouseArea.containsMouse) + if (root.currentIndex !== menuItemIndex) menuItem.closeMenu() } } |