linphone-desktop/tests/ui/modules/Common/Popup/AbstractDropDownMenu.qml

180 lines
3.5 KiB
QML

import QtQuick 2.7
import Common 1.0
import Common.Styles 1.0
import Utils 1.0
// ===================================================================
// Low component to display a list/menu in a popup.
// ===================================================================
Item {
id: menu
// Optionnal parameter, if defined and if a click is detected
// on it, menu is not closed.
property var launcher
// Optionnal parameters, set the position of Menu relative
// to this item.
property var relativeTo
property int relativeX: 0
property int relativeY: 0
default property alias _content: content.data
property bool _isOpen: false
signal menuClosed
signal menuOpened
// -----------------------------------------------------------------
function isOpen () {
return _isOpen
}
function showMenu () {
if (_isOpen) {
return
}
if (relativeTo != null) {
this.x = relativeTo.mapToItem(null, relativeX, relativeY).x
this.y = relativeTo.mapToItem(null, relativeX, relativeY).y
}
_isOpen = true
}
function hideMenu () {
if (!_isOpen) {
return
}
_isOpen = false
}
function _computeHeight () {
throw new Error('Virtual method must be implemented.')
}
// -----------------------------------------------------------------
implicitHeight: 0
opacity: 0
visible: false
z: Constants.zPopup
Keys.onEscapePressed: hideMenu()
// Set parent menu to root.
Component.onCompleted: {
if (relativeTo != null) {
parent = Utils.getTopParent(this)
}
}
// Block clicks, wheel... below menu.
MouseArea {
anchors.fill: parent
hoverEnabled: true
onWheel: {}
}
// Menu content.
Rectangle {
id: content
anchors.fill: parent
color: PopupStyle.backgroundColor
layer {
enabled: true
effect: PopupShadow {}
}
}
// Inverted mouse area to detect click outside menu.
InvertedMouseArea {
anchors.fill: parent
enabled: parent.visible
onPressed: {
if (launcher != null && pointIsInItem(launcher)) {
return
}
hideMenu()
}
}
// -----------------------------------------------------------------
states: State {
name: 'opened'
when: _isOpen
PropertyChanges {
focus: true // Necessary to use `Keys.onEscapePressed`.
implicitHeight: _computeHeight()
opacity: 1.0
target: menu
}
}
transitions: [
Transition {
from: ''
to: 'opened'
ScriptAction {
script: {
menu.visible = true
menuOpened()
}
}
NumberAnimation {
duration: PopupStyle.animation.openingDuration
easing.type: Easing.InOutQuad
property: 'opacity'
target: menu
}
NumberAnimation {
duration: PopupStyle.animation.openingDuration
easing.type: Easing.InOutQuad
property: 'implicitHeight'
target: menu
}
},
Transition {
from: 'opened'
to: ''
NumberAnimation {
duration: PopupStyle.animation.closingDuration
easing.type: Easing.InOutQuad
property: 'implicitHeight'
target: menu
}
SequentialAnimation {
ScriptAction {
script: menuClosed()
}
NumberAnimation {
duration: PopupStyle.animation.closingDuration
easing.type: Easing.InOutQuad
property: 'opacity'
target: menu
}
ScriptAction {
script: visible = false
}
}
}
]
}