diff options
Diffstat (limited to 'map-widget/qml/MapWidgetContextMenu.qml')
-rw-r--r-- | map-widget/qml/MapWidgetContextMenu.qml | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/map-widget/qml/MapWidgetContextMenu.qml b/map-widget/qml/MapWidgetContextMenu.qml new file mode 100644 index 000000000..17450a729 --- /dev/null +++ b/map-widget/qml/MapWidgetContextMenu.qml @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: GPL-2.0 +import QtQuick 2.0 + +Item { + id: container + signal actionSelected(int action) + + readonly property var actions: { + "OPEN_LOCATION_IN_GOOGLE_MAPS": 0, + "COPY_LOCATION_DECIMAL": 1, + "COPY_LOCATION_SEXAGESIMAL": 2, + "SELECT_VISIBLE_LOCATIONS": 3 + } + readonly property var menuItemData: [ + { idx: actions.OPEN_LOCATION_IN_GOOGLE_MAPS, itemText: qsTr("Open location in Google Maps") }, + { idx: actions.COPY_LOCATION_DECIMAL, itemText: qsTr("Copy location to clipboard (decimal)") }, + { idx: actions.COPY_LOCATION_SEXAGESIMAL, itemText: qsTr("Copy location to clipboard (sexagesimal)") }, + { idx: actions.SELECT_VISIBLE_LOCATIONS, itemText: qsTr("Select visible dive locations") } + ] + readonly property real itemTextPadding: 10.0 + readonly property real itemHeight: 34.0 + readonly property int itemAnimationDuration: 100 + readonly property color colorItemBackground: "#dedede" + readonly property color colorItemBackgroundSelected: "grey" + readonly property color colorItemText: "black" + readonly property color colorItemTextSelected: "#dedede" + readonly property color colorItemBorder: "black" + property int listViewIsVisible: -1 + property real maxItemWidth: 0.0 + + Image { + id: contextMenuImage + x: -width + source: "qrc:///mapwidget-context-menu" + + SequentialAnimation { + id:contextMenuImageAnimation + PropertyAnimation { target: contextMenuImage; property: "scale"; from: 1.0; to: 0.8; duration: 80 } + PropertyAnimation { target: contextMenuImage; property: "scale"; from: 0.8; to: 1.0; duration: 60 } + } + + MouseArea { + anchors.fill: parent + onClicked: { + contextMenuImageAnimation.restart() + listViewIsVisible = (listViewIsVisible !== 1) ? 1 : 0 + } + } + } + + ListModel { + id: listModel + property int selectedIdx: -1 + Component.onCompleted: { + for (var i = 0; i < menuItemData.length; i++) + append(menuItemData[i]); + } + } + + Component { + id: listItemDelegate + Rectangle { + color: model.idx === listModel.selectedIdx ? colorItemBackgroundSelected : colorItemBackground + width: maxItemWidth + height: itemHeight + border.color: colorItemBorder + Text { + x: itemTextPadding + height: itemHeight + verticalAlignment: Text.AlignVCenter + text: model.itemText + font.pointSize: 10.0 + color: model.idx === listModel.selectedIdx ? colorItemTextSelected : colorItemText + onWidthChanged: { + if (width + itemTextPadding * 2.0 > maxItemWidth) + maxItemWidth = width + itemTextPadding * 2.0 + } + Behavior on color { ColorAnimation { duration: itemAnimationDuration }} + } + Behavior on color { ColorAnimation { duration: itemAnimationDuration }} + } + } + + ListView { + id: listView + y: contextMenuImage.y + contextMenuImage.height + 10; + width: maxItemWidth; + height: listModel.count * itemHeight + visible: false + opacity: 0.0 + interactive: false + model: listModel + delegate: listItemDelegate + + onCountChanged: x = -maxItemWidth + onVisibleChanged: listModel.selectedIdx = -1 + onOpacityChanged: visible = opacity != 0.0 + + Timer { + id: timerListViewVisible + running: false + repeat: false + interval: itemAnimationDuration + 50 + onTriggered: listViewIsVisible = 0 + } + + MouseArea { + anchors.fill: parent + onClicked: { + if (opacity < 1.0) + return; + var idx = listView.indexAt(mouseX, mouseY) + listModel.selectedIdx = idx + container.actionSelected(idx) + timerListViewVisible.restart() + } + } + states: [ + State { when: listViewIsVisible === 1; PropertyChanges { target: listView; opacity: 1.0 }}, + State { when: listViewIsVisible === 0; PropertyChanges { target: listView; opacity: 0.0 }} + ] + transitions: Transition { NumberAnimation { properties: "opacity"; easing.type: Easing.InOutQuad }} + } +} |