mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-01-18 20:08:11 +00:00
113 lines
3.1 KiB
QML
113 lines
3.1 KiB
QML
import QtQuick 2.7
|
|
|
|
import Common 1.0
|
|
import Utils 1.0
|
|
|
|
// =============================================================================
|
|
// Helper to handle button click outside an item.
|
|
// =============================================================================
|
|
|
|
Item {
|
|
id: item
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
property bool _mouseAlwaysOutside
|
|
property var _mouseArea: null
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
// 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 () {
|
|
var parent = Utils.getTopParent(item, true)
|
|
|
|
if (_mouseArea == null) {
|
|
_mouseArea = builder.createObject()
|
|
}
|
|
|
|
_mouseArea.parent = parent
|
|
|
|
// Must be true if a fake parent is used and if `mouseArea`
|
|
// is not in the same window that `item`.
|
|
_mouseAlwaysOutside =
|
|
_mouseArea.parent !== Utils.getTopParent(item)
|
|
}
|
|
|
|
function _deleteMouseArea () {
|
|
if (_mouseArea != null) {
|
|
_mouseArea.destroy()
|
|
_mouseArea = null
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
// It's necessary to use a `enabled` variable.
|
|
// See: http://doc.qt.io/qt-5/qml-qtqml-component.html#completed-signal
|
|
//
|
|
// The creation order of components in a view is undefined,
|
|
// so the mouse area must be created only when the target component
|
|
// was completed.
|
|
Component.onCompleted: enabled && _createMouseArea()
|
|
Component.onDestruction: _deleteMouseArea()
|
|
|
|
onEnabledChanged: {
|
|
_deleteMouseArea()
|
|
|
|
if (enabled) {
|
|
_createMouseArea()
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: builder
|
|
|
|
MouseArea {
|
|
property var _timeout
|
|
|
|
function _checkPosition (positionEvent) {
|
|
// Propagate event.
|
|
positionEvent.accepted = false
|
|
|
|
// Click is outside or not.
|
|
if (
|
|
_mouseAlwaysOutside ||
|
|
!Utils.pointIsInItem(this, item, positionEvent)
|
|
) {
|
|
if (_timeout != null) {
|
|
// Remove existing timeout to avoid the creation of
|
|
// many children.
|
|
Utils.clearTimeout(_timeout)
|
|
}
|
|
|
|
// Use a asynchronous call that is executed
|
|
// after the propagated event.
|
|
//
|
|
// It's useful to ensure the window's context is not
|
|
// modified with the positionEvent before the `onPressed`
|
|
// call.
|
|
//
|
|
// The timeout is destroyed with the `MouseArea` component.
|
|
_timeout = Utils.setTimeout(this, 0, item.pressed.bind(
|
|
this,
|
|
(function (point, item) {
|
|
return Utils.pointIsInItem(this, item, point)
|
|
}).bind(this, { x: positionEvent.x, y: positionEvent.y })
|
|
))
|
|
}
|
|
}
|
|
|
|
anchors.fill: parent
|
|
propagateComposedEvents: true
|
|
z: Constants.zMax
|
|
|
|
onPressed: _checkPosition.call(this, mouse)
|
|
onWheel: _checkPosition.call(this, wheel)
|
|
}
|
|
}
|
|
}
|