mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-12-23 01:55:48 -05:00
ADS-B: Add QT 6 support for map.
This commit is contained in:
parent
0d333a910e
commit
7238b48e22
@ -4875,8 +4875,11 @@ ADSBDemodGUI::ADSBDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, Baseb
|
||||
ui->map->rootContext()->setContextProperty("airportModel", &m_airportModel);
|
||||
ui->map->rootContext()->setContextProperty("airspaceModel", &m_airspaceModel);
|
||||
ui->map->rootContext()->setContextProperty("navAidModel", &m_navAidModel);
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
|
||||
ui->map->setSource(QUrl(QStringLiteral("qrc:/map/map.qml")));
|
||||
|
||||
#else
|
||||
ui->map->setSource(QUrl(QStringLiteral("qrc:/map/map_6.qml")));
|
||||
#endif
|
||||
connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onMenuDialogCalled(const QPoint &)));
|
||||
|
||||
m_adsbDemod = reinterpret_cast<ADSBDemod*>(rxChannel); //new ADSBDemod(m_deviceUISet->m_deviceSourceAPI);
|
||||
|
@ -1,6 +1,8 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>map/map.qml</file>
|
||||
<file>map/map_6.qml</file>
|
||||
<file>map/ModifiedMapView.qml</file>
|
||||
<file>map/MapStation.qml</file>
|
||||
<file>map/aircraft_2engine.png</file>
|
||||
<file>map/aircraft_2enginesmall.png</file>
|
||||
|
178
plugins/channelrx/demodadsb/map/ModifiedMapView.qml
Normal file
178
plugins/channelrx/demodadsb/map/ModifiedMapView.qml
Normal file
@ -0,0 +1,178 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
import QtQuick
|
||||
import QtLocation as QL
|
||||
import QtPositioning as QP
|
||||
import Qt.labs.animation
|
||||
/*!
|
||||
\qmltype MapView
|
||||
\inqmlmodule QtLocation
|
||||
\brief An interactive map viewer component.
|
||||
|
||||
MapView wraps a Map and adds the typical interactive features:
|
||||
changing the zoom level, panning and tilting the map.
|
||||
|
||||
The implementation is a QML assembly of smaller building blocks that are
|
||||
available separately. In case you want to make changes in your own version
|
||||
of this component, you can copy the QML, which is installed into the
|
||||
\c qml/QtLocation module directory, and modify it as needed.
|
||||
|
||||
\sa Map
|
||||
*/
|
||||
Item {
|
||||
/*!
|
||||
\qmlproperty Map MapView::map
|
||||
|
||||
This property provides access to the underlying Map instance.
|
||||
*/
|
||||
property alias map: map
|
||||
|
||||
/*!
|
||||
\qmlproperty real minimumZoomLevel
|
||||
|
||||
The minimum zoom level according to the size of the view.
|
||||
|
||||
\sa Map::minimumZoomLevel
|
||||
*/
|
||||
property real minimumZoomLevel: map.minimumZoomLevel
|
||||
|
||||
/*!
|
||||
\qmlproperty real maximumZoomLevel
|
||||
|
||||
The maximum valid zoom level for the map.
|
||||
|
||||
\sa Map::maximumZoomLevel
|
||||
*/
|
||||
property real maximumZoomLevel: map.maximumZoomLevel
|
||||
|
||||
// --------------------------------
|
||||
// implementation
|
||||
id: root
|
||||
Component.onCompleted: map.resetPinchMinMax()
|
||||
|
||||
QL.Map {
|
||||
id: map
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
tilt: tiltHandler.persistentTranslation.y / -5
|
||||
property bool pinchAdjustingZoom: false
|
||||
|
||||
BoundaryRule on zoomLevel {
|
||||
id: br
|
||||
minimum: map.minimumZoomLevel
|
||||
maximum: map.maximumZoomLevel
|
||||
}
|
||||
|
||||
onZoomLevelChanged: {
|
||||
br.returnToBounds();
|
||||
if (!pinchAdjustingZoom) resetPinchMinMax()
|
||||
}
|
||||
|
||||
function resetPinchMinMax() {
|
||||
pinch.persistentScale = 1
|
||||
pinch.scaleAxis.minimum = Math.pow(2, root.minimumZoomLevel - map.zoomLevel + 1)
|
||||
pinch.scaleAxis.maximum = Math.pow(2, root.maximumZoomLevel - map.zoomLevel - 1)
|
||||
}
|
||||
|
||||
PinchHandler {
|
||||
id: pinch
|
||||
target: null
|
||||
property real rawBearing: 0
|
||||
property QP.geoCoordinate startCentroid
|
||||
onActiveChanged: if (active) {
|
||||
flickAnimation.stop()
|
||||
pinch.startCentroid = map.toCoordinate(pinch.centroid.position, false)
|
||||
} else {
|
||||
flickAnimation.restart(centroid.velocity)
|
||||
map.resetPinchMinMax()
|
||||
}
|
||||
onScaleChanged: (delta) => {
|
||||
map.pinchAdjustingZoom = true
|
||||
map.zoomLevel += Math.log2(delta)
|
||||
map.alignCoordinateToPoint(pinch.startCentroid, pinch.centroid.position)
|
||||
map.pinchAdjustingZoom = false
|
||||
}
|
||||
onRotationChanged: (delta) => {
|
||||
pinch.rawBearing -= delta
|
||||
// snap to 0° if we're close enough
|
||||
map.bearing = (Math.abs(pinch.rawBearing) < 5) ? 0 : pinch.rawBearing
|
||||
map.alignCoordinateToPoint(pinch.startCentroid, pinch.centroid.position)
|
||||
}
|
||||
grabPermissions: PointerHandler.TakeOverForbidden
|
||||
}
|
||||
WheelHandler {
|
||||
id: wheel
|
||||
// workaround for QTBUG-87646 / QTBUG-112394 / QTBUG-112432:
|
||||
// Magic Mouse pretends to be a trackpad but doesn't work with PinchHandler
|
||||
// and we don't yet distinguish mice and trackpads on Wayland either
|
||||
acceptedDevices: Qt.platform.pluginName === "cocoa" || Qt.platform.pluginName === "wayland"
|
||||
? PointerDevice.Mouse | PointerDevice.TouchPad
|
||||
: PointerDevice.Mouse
|
||||
onWheel: (event) => {
|
||||
const loc = map.toCoordinate(wheel.point.position)
|
||||
switch (event.modifiers) {
|
||||
case Qt.NoModifier:
|
||||
// jonb - Changed to make more like Qt5
|
||||
//map.zoomLevel += event.angleDelta.y / 120
|
||||
map.zoomLevel += event.angleDelta.y / 1000
|
||||
break
|
||||
case Qt.ShiftModifier:
|
||||
map.bearing += event.angleDelta.y / 15
|
||||
break
|
||||
case Qt.ControlModifier:
|
||||
map.tilt += event.angleDelta.y / 15
|
||||
break
|
||||
}
|
||||
map.alignCoordinateToPoint(loc, wheel.point.position)
|
||||
}
|
||||
}
|
||||
DragHandler {
|
||||
id: drag
|
||||
signal flickStarted // for autotests only
|
||||
signal flickEnded
|
||||
target: null
|
||||
onTranslationChanged: (delta) => map.pan(-delta.x, -delta.y)
|
||||
onActiveChanged: if (active) {
|
||||
flickAnimation.stop()
|
||||
} else {
|
||||
flickAnimation.restart(centroid.velocity)
|
||||
}
|
||||
}
|
||||
|
||||
property vector3d animDest
|
||||
onAnimDestChanged: if (flickAnimation.running) {
|
||||
const delta = Qt.vector2d(animDest.x - flickAnimation.animDestLast.x, animDest.y - flickAnimation.animDestLast.y)
|
||||
map.pan(-delta.x, -delta.y)
|
||||
flickAnimation.animDestLast = animDest
|
||||
}
|
||||
|
||||
Vector3dAnimation on animDest {
|
||||
id: flickAnimation
|
||||
property vector3d animDestLast
|
||||
from: Qt.vector3d(0, 0, 0)
|
||||
duration: 500
|
||||
easing.type: Easing.OutQuad
|
||||
onStarted: drag.flickStarted()
|
||||
onStopped: drag.flickEnded()
|
||||
|
||||
function restart(vel) {
|
||||
stop()
|
||||
map.animDest = Qt.vector3d(0, 0, 0)
|
||||
animDestLast = Qt.vector3d(0, 0, 0)
|
||||
to = Qt.vector3d(vel.x / duration * 100, vel.y / duration * 100, 0)
|
||||
start()
|
||||
}
|
||||
}
|
||||
|
||||
DragHandler {
|
||||
id: tiltHandler
|
||||
minimumPointCount: 2
|
||||
maximumPointCount: 2
|
||||
target: null
|
||||
xAxis.enabled: false
|
||||
grabPermissions: PointerHandler.TakeOverForbidden
|
||||
onActiveChanged: if (active) flickAnimation.stop()
|
||||
}
|
||||
}
|
||||
}
|
537
plugins/channelrx/demodadsb/map/map_6.qml
Normal file
537
plugins/channelrx/demodadsb/map/map_6.qml
Normal file
@ -0,0 +1,537 @@
|
||||
import QtQuick 2.14
|
||||
import QtQuick.Window 2.14
|
||||
import QtQuick.Controls 2.14
|
||||
import QtPositioning 6.5
|
||||
import QtLocation 6.5
|
||||
import Qt5Compat.GraphicalEffects
|
||||
|
||||
Item {
|
||||
id: qmlMap
|
||||
property int aircraftZoomLevel: 11
|
||||
property int aircraftMinZoomLevel: 11
|
||||
property int airportZoomLevel: 11
|
||||
property string mapProvider: "osm"
|
||||
property variant mapPtr
|
||||
property string requestedMapType
|
||||
property bool lightIcons
|
||||
property variant guiPtr
|
||||
property bool smoothing
|
||||
|
||||
function createMap(pluginParameters, requestedMap, gui) {
|
||||
requestedMapType = requestedMap
|
||||
guiPtr = gui
|
||||
|
||||
var paramString = ""
|
||||
for (var prop in pluginParameters) {
|
||||
var parameter = 'PluginParameter { name: "' + prop + '"; value: "' + pluginParameters[prop] + '"}'
|
||||
paramString = paramString + parameter
|
||||
}
|
||||
var pluginString = 'import QtLocation 6.5; Plugin{ name:"' + mapProvider + '"; ' + paramString + '}'
|
||||
var plugin = Qt.createQmlObject (pluginString, qmlMap)
|
||||
|
||||
if (mapPtr) {
|
||||
// Objects aren't destroyed immediately, so don't call findChild("map")
|
||||
mapPtr.destroy()
|
||||
mapPtr = null
|
||||
}
|
||||
mapPtr = actualMapComponent.createObject(page)
|
||||
mapPtr.map.plugin = plugin
|
||||
mapPtr.map.forceActiveFocus()
|
||||
return mapPtr
|
||||
}
|
||||
|
||||
Item {
|
||||
id: page
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
Component {
|
||||
id: actualMapComponent
|
||||
|
||||
ModifiedMapView {
|
||||
id: mapView
|
||||
objectName: "mapView"
|
||||
anchors.fill: parent
|
||||
map.center: QtPositioning.coordinate(51.5, 0.125) // London
|
||||
map.zoomLevel: 10
|
||||
map.objectName: "map"
|
||||
|
||||
// not in 6
|
||||
//gesture.enabled: true
|
||||
//gesture.acceptedGestures: MapGestureArea.PinchGesture | MapGestureArea.PanGesture
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
propagateComposedEvents: true
|
||||
onClicked: {
|
||||
// Unhighlight current aircraft
|
||||
guiPtr.clearHighlighted()
|
||||
mouse.accepted = false
|
||||
}
|
||||
}
|
||||
|
||||
MapStation {
|
||||
id: station
|
||||
objectName: "station"
|
||||
stationName: "Home"
|
||||
}
|
||||
|
||||
MapItemView {
|
||||
model: airspaceModel
|
||||
delegate: airspaceComponent
|
||||
parent: mapView.map
|
||||
}
|
||||
|
||||
MapItemView {
|
||||
model: navAidModel
|
||||
delegate: navAidComponent
|
||||
parent: mapView.map
|
||||
}
|
||||
|
||||
MapItemView {
|
||||
model: airspaceModel
|
||||
delegate: airspaceNameComponent
|
||||
parent: mapView.map
|
||||
}
|
||||
|
||||
MapItemView {
|
||||
model: airportModel
|
||||
delegate: airportComponent
|
||||
parent: mapView.map
|
||||
}
|
||||
|
||||
// This needs to be before aircraftComponent MapItemView, so it's drawn underneath
|
||||
MapItemView {
|
||||
model: aircraftModel
|
||||
delegate: aircraftPathComponent
|
||||
parent: mapView.map
|
||||
}
|
||||
|
||||
MapItemView {
|
||||
model: aircraftModel
|
||||
delegate: aircraftComponent
|
||||
parent: mapView.map
|
||||
}
|
||||
|
||||
map.onZoomLevelChanged: {
|
||||
if (map.zoomLevel > aircraftMinZoomLevel) {
|
||||
aircraftZoomLevel = map.zoomLevel
|
||||
} else {
|
||||
aircraftZoomLevel = aircraftMinZoomLevel
|
||||
}
|
||||
if (map.zoomLevel > 11) {
|
||||
station.zoomLevel = map.zoomLevel
|
||||
airportZoomLevel = map.zoomLevel
|
||||
} else {
|
||||
station.zoomLevel = 11
|
||||
airportZoomLevel = 11
|
||||
}
|
||||
}
|
||||
|
||||
map.onSupportedMapTypesChanged : {
|
||||
for (var i = 0; i < map.supportedMapTypes.length; i++) {
|
||||
if (requestedMapType == map.supportedMapTypes[i].name) {
|
||||
map.activeMapType = map.supportedMapTypes[i]
|
||||
}
|
||||
}
|
||||
lightIcons = (requestedMapType == "Night Transit Map") || (requestedMapType == "mapbox://styles/mapbox/dark-v9")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: navAidComponent
|
||||
MapQuickItem {
|
||||
id: navAid
|
||||
anchorPoint.x: image.width/2
|
||||
anchorPoint.y: image.height/2
|
||||
coordinate: position
|
||||
zoomLevel: airportZoomLevel
|
||||
|
||||
sourceItem: Grid {
|
||||
columns: 1
|
||||
Grid {
|
||||
horizontalItemAlignment: Grid.AlignHCenter
|
||||
columnSpacing: 5
|
||||
layer.enabled: smoothing
|
||||
layer.smooth: smoothing
|
||||
Image {
|
||||
id: image
|
||||
source: navAidImage
|
||||
visible: !lightIcons
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: (mouse) => {
|
||||
selected = !selected
|
||||
}
|
||||
}
|
||||
}
|
||||
ColorOverlay {
|
||||
cached: true
|
||||
width: image.width
|
||||
height: image.height
|
||||
source: image
|
||||
color: "#c0ffffff"
|
||||
visible: lightIcons
|
||||
}
|
||||
Rectangle {
|
||||
id: bubble
|
||||
color: bubbleColour
|
||||
border.width: 1
|
||||
width: text.width + 5
|
||||
height: text.height + 5
|
||||
radius: 5
|
||||
Text {
|
||||
id: text
|
||||
anchors.centerIn: parent
|
||||
text: navAidData
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: (mouse) => {
|
||||
selected = !selected
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: airspaceComponent
|
||||
MapPolygon {
|
||||
border.width: 1
|
||||
border.color: airspaceBorderColor
|
||||
color: airspaceFillColor
|
||||
path: airspacePolygon
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: airspaceNameComponent
|
||||
MapQuickItem {
|
||||
coordinate: position
|
||||
anchorPoint.x: airspaceText.width/2
|
||||
anchorPoint.y: airspaceText.height/2
|
||||
zoomLevel: airportZoomLevel
|
||||
sourceItem: Grid {
|
||||
columns: 1
|
||||
Grid {
|
||||
layer.enabled: smoothing
|
||||
layer.smooth: smoothing
|
||||
horizontalItemAlignment: Grid.AlignHCenter
|
||||
Text {
|
||||
id: airspaceText
|
||||
text: details
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: aircraftPathComponent
|
||||
MapPolyline {
|
||||
line.width: 2
|
||||
line.color: 'gray'
|
||||
path: aircraftPath
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: aircraftComponent
|
||||
MapQuickItem {
|
||||
id: aircraft
|
||||
anchorPoint.x: image.width/2
|
||||
anchorPoint.y: image.height/2
|
||||
coordinate: position
|
||||
zoomLevel: aircraftZoomLevel
|
||||
|
||||
sourceItem: Grid {
|
||||
columns: 1
|
||||
Grid {
|
||||
layer.enabled: smoothing
|
||||
layer.smooth: smoothing
|
||||
horizontalItemAlignment: Grid.AlignHCenter
|
||||
Image {
|
||||
id: image
|
||||
rotation: heading
|
||||
source: aircraftImage
|
||||
visible: !lightIcons
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
onClicked: {
|
||||
if (mouse.button === Qt.LeftButton) {
|
||||
highlighted = true
|
||||
console.log("z=" + aircraft.sourceItem.z)
|
||||
aircraft.sourceItem.z = aircraft.sourceItem.z + 1
|
||||
} else if (mouse.button === Qt.RightButton) {
|
||||
contextMenu.popup()
|
||||
}
|
||||
}
|
||||
onDoubleClicked: {
|
||||
target = true
|
||||
}
|
||||
}
|
||||
}
|
||||
ColorOverlay {
|
||||
cached: true
|
||||
width: image.width
|
||||
height: image.height
|
||||
rotation: heading
|
||||
source: image
|
||||
color: "#c0ffffff"
|
||||
visible: lightIcons
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
highlighted = true
|
||||
}
|
||||
onDoubleClicked: {
|
||||
target = true
|
||||
}
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
id: bubble
|
||||
color: bubbleColour
|
||||
border.width: 1
|
||||
width: text.width * 1.1
|
||||
height: text.height * 1.1
|
||||
radius: 5
|
||||
Text {
|
||||
id: text
|
||||
anchors.centerIn: parent
|
||||
text: adsbData
|
||||
textFormat: TextEdit.RichText
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
onClicked: {
|
||||
if (mouse.button === Qt.LeftButton) {
|
||||
showAll = !showAll
|
||||
} else if (mouse.button === Qt.RightButton) {
|
||||
contextMenu.popup()
|
||||
}
|
||||
}
|
||||
Menu {
|
||||
id: contextMenu
|
||||
MenuItem {
|
||||
text: "Set as target"
|
||||
onTriggered: target = true
|
||||
}
|
||||
MenuItem {
|
||||
text: "Find on feature map"
|
||||
onTriggered: aircraftModel.findOnMap(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: airportComponent
|
||||
MapItemGroup {
|
||||
MapItemGroup {
|
||||
property var groupVisible: false
|
||||
id: rangeGroup
|
||||
MapCircle {
|
||||
id: circle5nm
|
||||
center: position
|
||||
color: "transparent"
|
||||
border.color: "gray"
|
||||
radius: 9260 // 5nm in metres
|
||||
visible: rangeGroup.groupVisible
|
||||
}
|
||||
MapCircle {
|
||||
id: circle10nm
|
||||
center: position
|
||||
color: "transparent"
|
||||
border.color: "gray"
|
||||
radius: 18520
|
||||
visible: rangeGroup.groupVisible
|
||||
}
|
||||
MapCircle {
|
||||
id: circle15nm
|
||||
center: airport.coordinate
|
||||
color: "transparent"
|
||||
border.color: "gray"
|
||||
radius: 27780
|
||||
visible: rangeGroup.groupVisible
|
||||
}
|
||||
MapQuickItem {
|
||||
id: text5nm
|
||||
coordinate {
|
||||
latitude: position.latitude
|
||||
longitude: position.longitude + (5/60)/Math.cos(Math.abs(position.latitude)*Math.PI/180)
|
||||
}
|
||||
anchorPoint.x: 0
|
||||
anchorPoint.y: height/2
|
||||
sourceItem: Text {
|
||||
color: "grey"
|
||||
text: "5nm"
|
||||
}
|
||||
visible: rangeGroup.groupVisible
|
||||
}
|
||||
MapQuickItem {
|
||||
id: text10nm
|
||||
coordinate {
|
||||
latitude: position.latitude
|
||||
longitude: position.longitude + (10/60)/Math.cos(Math.abs(position.latitude)*Math.PI/180)
|
||||
}
|
||||
anchorPoint.x: 0
|
||||
anchorPoint.y: height/2
|
||||
sourceItem: Text {
|
||||
color: "grey"
|
||||
text: "10nm"
|
||||
}
|
||||
visible: rangeGroup.groupVisible
|
||||
}
|
||||
MapQuickItem {
|
||||
id: text15nm
|
||||
coordinate {
|
||||
latitude: position.latitude
|
||||
longitude: position.longitude + (15/60)/Math.cos(Math.abs(position.latitude)*Math.PI/180)
|
||||
}
|
||||
anchorPoint.x: 0
|
||||
anchorPoint.y: height/2
|
||||
sourceItem: Text {
|
||||
color: "grey"
|
||||
text: "15nm"
|
||||
}
|
||||
visible: rangeGroup.groupVisible
|
||||
}
|
||||
}
|
||||
|
||||
MapQuickItem {
|
||||
id: airport
|
||||
anchorPoint.x: image.width/2
|
||||
anchorPoint.y: image.height/2
|
||||
coordinate: position
|
||||
zoomLevel: airportZoomLevel
|
||||
sourceItem: Grid {
|
||||
columns: 1
|
||||
Grid {
|
||||
horizontalItemAlignment: Grid.AlignHCenter
|
||||
layer.enabled: smoothing
|
||||
layer.smooth: smoothing
|
||||
Image {
|
||||
id: image
|
||||
source: airportImage
|
||||
visible: !lightIcons
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
onClicked: (mouse) => {
|
||||
console.log("AIRPORT CLICKED ************************* ");
|
||||
if (mouse.button === Qt.RightButton) {
|
||||
showRangeItem.visible = !rangeGroup.groupVisible
|
||||
hideRangeItem.visible = rangeGroup.groupVisible
|
||||
menuItems.clear()
|
||||
var scanners = airportModel.getFreqScanners()
|
||||
for (var i = 0; i < scanners.length; i++) {
|
||||
menuItems.append({
|
||||
text: "Send to Frequency Scanner " + scanners[i],
|
||||
airport: index,
|
||||
scanner: scanners[i]
|
||||
})
|
||||
}
|
||||
contextMenu.popup()
|
||||
}
|
||||
}
|
||||
onDoubleClicked: (mouse) => {
|
||||
rangeGroup.groupVisible = !rangeGroup.groupVisible
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: menuItems
|
||||
}
|
||||
|
||||
Menu {
|
||||
id: contextMenu
|
||||
MenuItem {
|
||||
id: showRangeItem
|
||||
text: "Show range rings"
|
||||
onTriggered: rangeGroup.groupVisible = true
|
||||
height: visible ? implicitHeight : 0
|
||||
}
|
||||
MenuItem {
|
||||
id: hideRangeItem
|
||||
text: "Hide range rings"
|
||||
onTriggered: rangeGroup.groupVisible = false
|
||||
height: visible ? implicitHeight : 0
|
||||
}
|
||||
Instantiator {
|
||||
model: menuItems
|
||||
MenuItem {
|
||||
text: model.text
|
||||
onTriggered: airportModel.sendToFreqScanner(model.airport, model.scanner)
|
||||
}
|
||||
onObjectAdded: function(index, object) {
|
||||
contextMenu.insertItem(index, object)
|
||||
}
|
||||
onObjectRemoved: function(index, object) {
|
||||
contextMenu.removeItem(object)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ColorOverlay {
|
||||
cached: true
|
||||
width: image.width
|
||||
height: image.height
|
||||
source: image
|
||||
color: "#c0ffffff"
|
||||
visible: lightIcons
|
||||
}
|
||||
Rectangle {
|
||||
id: bubble
|
||||
color: bubbleColour
|
||||
border.width: 1
|
||||
width: text.width + 5
|
||||
height: text.height + 5
|
||||
radius: 5
|
||||
Text {
|
||||
id: text
|
||||
anchors.centerIn: parent
|
||||
text: airportData
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: (mouse) => {
|
||||
console.log("AIRPORT 2 CLICKED ************************* ");
|
||||
if (showFreq) {
|
||||
var freqIdx = Math.floor((mouse.y-5)/((height-10)/airportDataRows))
|
||||
if (freqIdx == 0) {
|
||||
showFreq = false
|
||||
}
|
||||
} else {
|
||||
showFreq = true
|
||||
}
|
||||
}
|
||||
onDoubleClicked: (mouse) => {
|
||||
if (showFreq) {
|
||||
var freqIdx = Math.floor((mouse.y-5)/((height-10)/airportDataRows))
|
||||
if (freqIdx != 0) {
|
||||
selectedFreq = freqIdx - 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user