subsurface/mobile-widgets/qml/MapWidgetContextMenu.qml
Lubomir I. Ivanov 4d0d0e102b mapwidgetcontextmenu: add the actionSelected() signal
The actionSelected() signal is now dispatched when the user selects
an action from the menu (see the "actions" object). Then the declaration
of the MapWidgetContextMenu object in mapwidget.qml can catch that
signal in the onActionSelected() slot and obtain the action via
switch() branching.

The actions enumeration is kept in QML for now, with the idea that
specific C++ methods from the mapwidgethelper class will be called
directly (if marked as Q_INVOCABLE), instead of a generic
onMapAction(action) C++ method in the helper. But if the actions
are possible from QML (like copying to clipboard) and are also
small and non-expensive, it might be better to keep them
in mapwidget.qml.

Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
2017-07-28 07:31:11 -07:00

127 lines
3.5 KiB
QML

// SPDX-License-Identifier: GPL-2.0
import QtQuick 2.7
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
}
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)") }
]
readonly property real itemTextPadding: 10.0
readonly property real itemHeight: 30.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
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 }
}
}
}