mirror of
https://github.com/subsurface/subsurface.git
synced 2024-11-28 13:10:19 +00:00
4d0d0e102b
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>
127 lines
3.5 KiB
QML
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 }
|
|
}
|
|
}
|
|
}
|