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
import Utils 1.0
// ===================================================================
// Helper to handle button click outside a component.
// Helper to handle button click outside an item.
// ===================================================================
Item {
......@@ -12,7 +12,9 @@ Item {
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 () {
if (_mouseArea == null) {
......@@ -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.
// See: http://doc.qt.io/qt-5/qml-qtqml-component.html#completed-signal
//
......@@ -70,9 +63,7 @@ Item {
mouse.accepted = false
// Click is outside or not.
if (!_isInItem(
mapToItem(item.parent, mouse.x, mouse.y)
)) {
if (!Utils.pointIsInItem(this, item, mouse)) {
if (_timeout != null) {
// Remove existing timeout to avoid the creation of
// many children.
......@@ -87,9 +78,12 @@ Item {
// call.
//
// The timeout is destroyed with the `MouseArea` component.
_timeout = Utils.setTimeout(
this, 0, item.pressed.bind(this)
)
_timeout = Utils.setTimeout(this, 0, item.pressed.bind(
this,
(function (point, item) {
return Utils.pointIsInItem(this, item, point)
}).bind(this, { x: mouse.x, y: mouse.y })
))
}
}
}
......
......@@ -12,6 +12,7 @@ Rectangle {
property bool drawOnRoot: false
property int entryHeight // Only with a ListView child.
property int maxMenuHeight // Only with a ListView child.
property var launcher
property var relativeTo
default property alias _content: content.data
......@@ -82,6 +83,11 @@ Rectangle {
anchors.fill: parent
enabled: parent.visible
onPressed: hideMenu()
onPressed: {
if (launcher != null && pointIsInItem(launcher)) {
return
}
hideMenu()
}
}
}
......@@ -67,6 +67,7 @@ Item {
id: menu
anchors.top: searchField.bottom
launcher: searchField
width: searchField.width
onMenuClosed: _hideMenu()
......
......@@ -55,6 +55,7 @@ RowLayout {
entryHeight: 22
height: 100
width: 120
launcher: button
relativeTo: button
Rectangle {
......
......@@ -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[`.
// Return a mapped array created with the returned values of `cb`.
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