Commit eca28cc5 authored by Ronan Abhamon's avatar Ronan Abhamon

fix(Popup/DropDownMenu): don't hide menu if launcher button is clicked again

parent 1de6a8bd
...@@ -4,7 +4,7 @@ import Common 1.0 ...@@ -4,7 +4,7 @@ import Common 1.0
import Utils 1.0 import Utils 1.0
// =================================================================== // ===================================================================
// Helper to handle button click outside a component. // Helper to handle button click outside an item.
// =================================================================== // ===================================================================
Item { Item {
...@@ -12,7 +12,9 @@ Item { ...@@ -12,7 +12,9 @@ Item {
property var _mouseArea property var _mouseArea
signal pressed // When emitted, returns a function to test if the click
// is on a specific item. It takes only a item parameter.
signal pressed (var pointIsInItem)
function _createMouseArea () { function _createMouseArea () {
if (_mouseArea == null) { if (_mouseArea == null) {
...@@ -29,15 +31,6 @@ Item { ...@@ -29,15 +31,6 @@ Item {
} }
} }
function _isInItem (point) {
return (
point.x >= item.x &&
point.y >= item.y &&
point.x < item.x + item.width &&
point.y < item.y + item.height
)
}
// It's necessary to use a `enabled` variable. // It's necessary to use a `enabled` variable.
// See: http://doc.qt.io/qt-5/qml-qtqml-component.html#completed-signal // See: http://doc.qt.io/qt-5/qml-qtqml-component.html#completed-signal
// //
...@@ -70,9 +63,7 @@ Item { ...@@ -70,9 +63,7 @@ Item {
mouse.accepted = false mouse.accepted = false
// Click is outside or not. // Click is outside or not.
if (!_isInItem( if (!Utils.pointIsInItem(this, item, mouse)) {
mapToItem(item.parent, mouse.x, mouse.y)
)) {
if (_timeout != null) { if (_timeout != null) {
// Remove existing timeout to avoid the creation of // Remove existing timeout to avoid the creation of
// many children. // many children.
...@@ -87,9 +78,12 @@ Item { ...@@ -87,9 +78,12 @@ Item {
// call. // call.
// //
// The timeout is destroyed with the `MouseArea` component. // The timeout is destroyed with the `MouseArea` component.
_timeout = Utils.setTimeout( _timeout = Utils.setTimeout(this, 0, item.pressed.bind(
this, 0, item.pressed.bind(this) this,
) (function (point, item) {
return Utils.pointIsInItem(this, item, point)
}).bind(this, { x: mouse.x, y: mouse.y })
))
} }
} }
} }
......
...@@ -12,6 +12,7 @@ Rectangle { ...@@ -12,6 +12,7 @@ Rectangle {
property bool drawOnRoot: false property bool drawOnRoot: false
property int entryHeight // Only with a ListView child. property int entryHeight // Only with a ListView child.
property int maxMenuHeight // Only with a ListView child. property int maxMenuHeight // Only with a ListView child.
property var launcher
property var relativeTo property var relativeTo
default property alias _content: content.data default property alias _content: content.data
...@@ -82,6 +83,11 @@ Rectangle { ...@@ -82,6 +83,11 @@ Rectangle {
anchors.fill: parent anchors.fill: parent
enabled: parent.visible enabled: parent.visible
onPressed: hideMenu() onPressed: {
if (launcher != null && pointIsInItem(launcher)) {
return
}
hideMenu()
}
} }
} }
...@@ -67,6 +67,7 @@ Item { ...@@ -67,6 +67,7 @@ Item {
id: menu id: menu
anchors.top: searchField.bottom anchors.top: searchField.bottom
launcher: searchField
width: searchField.width width: searchField.width
onMenuClosed: _hideMenu() onMenuClosed: _hideMenu()
......
...@@ -55,6 +55,7 @@ RowLayout { ...@@ -55,6 +55,7 @@ RowLayout {
entryHeight: 22 entryHeight: 22
height: 100 height: 100
width: 120 width: 120
launcher: button
relativeTo: button relativeTo: button
Rectangle { Rectangle {
......
...@@ -136,6 +136,24 @@ function qmlTypeof (object, className) { ...@@ -136,6 +136,24 @@ function qmlTypeof (object, className) {
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Test if a point is in a item.
//
// `source` is the item that generated the point.
// `target` is the item to test.
// `point` is the point to test.
function pointIsInItem (source, target, point) {
point = source.mapToItem(target.parent, point.x, point.y)
return (
point.x >= target.x &&
point.y >= target.y &&
point.x < target.x + target.width &&
point.y < target.y + target.height
)
}
// -------------------------------------------------------------------
// Invoke a `cb` function with each value of the interval: `[0, n[`. // Invoke a `cb` function with each value of the interval: `[0, n[`.
// Return a mapped array created with the returned values of `cb`. // Return a mapped array created with the returned values of `cb`.
function times (n, cb, context) { function times (n, cb, context) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment