diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index 9f76c55..4eeb642 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -14,6 +14,7 @@ src/ui/toolbar/ModeIndicator.qml src/ui/toolbar/MultiVehicleSelector.qml src/ui/toolbar/RCRSSIIndicator.qml + src/ui/toolbar/RemoteIDIndicator.qml src/ui/toolbar/ROIIndicator.qml src/ui/toolbar/TelemetryRSSIIndicator.qml src/ui/toolbar/VTOLModeIndicator.qml @@ -38,6 +39,7 @@ src/ui/preferences/BluetoothSettings.qml src/PlanView/CorridorScanEditor.qml src/ui/preferences/DebugWindow.qml + src/ui/preferences/RemoteIDSettings.qml src/AutoPilotPlugins/Common/ESP8266Component.qml src/AutoPilotPlugins/Common/ESP8266ComponentSummary.qml src/ui/ExitWithErrorWindow.qml @@ -298,6 +300,7 @@ src/MissionManager/CameraSection.FactMetaData.json src/MissionManager/CameraSpec.FactMetaData.json src/MissionManager/CorridorScan.SettingsGroup.json + src/Settings/RemoteID.SettingsGroup.json src/QmlControls/EditPositionDialog.FactMetaData.json src/Settings/FirmwareUpgrade.SettingsGroup.json src/Settings/FlightMap.SettingsGroup.json diff --git a/src/FirmwarePlugin/FirmwarePlugin.cc b/src/FirmwarePlugin/FirmwarePlugin.cc index 8b86cac..7f1f576 100644 --- a/src/FirmwarePlugin/FirmwarePlugin.cc +++ b/src/FirmwarePlugin/FirmwarePlugin.cc @@ -332,6 +332,7 @@ const QVariantList& FirmwarePlugin::toolIndicators(const Vehicle*) QVariant::fromValue(QUrl::fromUserInput("qrc:/toolbar/TelemetryRSSIIndicator.qml")), QVariant::fromValue(QUrl::fromUserInput("qrc:/toolbar/RCRSSIIndicator.qml")), QVariant::fromValue(QUrl::fromUserInput("qrc:/toolbar/BatteryIndicator.qml")), + QVariant::fromValue(QUrl::fromUserInput("qrc:/toolbar/RemoteIDIndicator.qml")), }); } return _toolIndicatorList; diff --git a/src/QGCApplication.cc b/src/QGCApplication.cc index 74e37c2..2a04772 100644 --- a/src/QGCApplication.cc +++ b/src/QGCApplication.cc @@ -102,6 +102,7 @@ #include "QGCMAVLink.h" #include "VehicleLinkManager.h" #include "Autotune.h" +#include "RemoteIDManager.h" #if defined(QGC_ENABLE_PAIRING) #include "PairingManager.h" @@ -463,6 +464,7 @@ void QGCApplication::_initCommon() qmlRegisterUncreatableType (kQGCVehicle, 1, 0, "LinkInterface", kRefOnly); qmlRegisterUncreatableType (kQGCVehicle, 1, 0, "VehicleLinkManager", kRefOnly); qmlRegisterUncreatableType (kQGCVehicle, 1, 0, "Autotune", kRefOnly); + qmlRegisterUncreatableType (kQGCVehicle, 1, 0, "remoteIDManager", kRefOnly); qmlRegisterUncreatableType (kQGCControllers, 1, 0, "MissionController", kRefOnly); qmlRegisterUncreatableType (kQGCControllers, 1, 0, "GeoFenceController", kRefOnly); diff --git a/src/api/QGCCorePlugin.cc b/src/api/QGCCorePlugin.cc index 4bc51f7..7e61747 100644 --- a/src/api/QGCCorePlugin.cc +++ b/src/api/QGCCorePlugin.cc @@ -71,6 +71,8 @@ public: if(pQmlTest) delete pQmlTest; #endif + if(pRemoteID) + delete pRemoteID; if(defaultOptions) delete defaultOptions; } @@ -95,6 +97,7 @@ public: QmlComponentInfo* pDebug = nullptr; QmlComponentInfo* pQmlTest = nullptr; #endif + QmlComponentInfo* pRemoteID = nullptr; QGCOptions* defaultOptions = nullptr; QVariantList settingsList; @@ -165,6 +168,9 @@ QVariantList &QGCCorePlugin::settingsPages() QUrl::fromUserInput("qrc:/qml/MavlinkSettings.qml"), QUrl::fromUserInput("qrc:/res/waves.svg")); _p->settingsList.append(QVariant::fromValue(reinterpret_cast(_p->pMAVLink))); + _p->pRemoteID = new QmlComponentInfo(tr("Remote ID"), + QUrl::fromUserInput("qrc:/qml/RemoteIDSettings.qml")); + _p->settingsList.append(QVariant::fromValue(reinterpret_cast(_p->pRemoteID))); _p->pConsole = new QmlComponentInfo(tr("Console"), QUrl::fromUserInput("qrc:/qml/QGroundControl/Controls/AppMessages.qml")); _p->settingsList.append(QVariant::fromValue(reinterpret_cast(_p->pConsole))); diff --git a/src/ui/AppSettings.qml b/src/ui/AppSettings.qml index b7a717c..ded4121 100644 --- a/src/ui/AppSettings.qml +++ b/src/ui/AppSettings.qml @@ -30,11 +30,18 @@ Rectangle { property bool _first: true + property bool _commingFromRIDSettings: false + QGCPalette { id: qgcPal } Component.onCompleted: { //-- Default Settings - __rightPanel.source = QGroundControl.corePlugin.settingsPages[QGroundControl.corePlugin.defaultSettings].url + if (globals.commingFromRIDIndicator) { + __rightPanel.source = "qrc:/qml/RemoteIDSettings.qml" + globals.commingFromRIDIndicator = false + } else { + __rightPanel.source = QGroundControl.corePlugin.settingsPages[QGroundControl.corePlugin.defaultSettings].url + } } QGCFlickable { @@ -62,6 +69,7 @@ Rectangle { text: modelData.title autoExclusive: true Layout.fillWidth: true + visible: modelData.url != "qrc:/qml/RemoteIDSettings.qml" ? true : QGroundControl.settingsManager.remoteIDSettings.enable.rawValue onClicked: { if (mainWindow.preventViewSwitch()) { @@ -74,10 +82,20 @@ Rectangle { } Component.onCompleted: { + if (globals.commingFromRIDIndicator) { + _commingFromRIDSettings = true + } if(_first) { _first = false checked = true } + if (_commingFromRIDSettings) { + checked = false + _commingFromRIDSettings = false + if (modelData.url == "qrc:/qml/RemoteIDSettings.qml") { + checked = true + } + } } } } diff --git a/src/ui/MainRootWindow.qml b/src/ui/MainRootWindow.qml index 4895e4f..199f6eb 100644 --- a/src/ui/MainRootWindow.qml +++ b/src/ui/MainRootWindow.qml @@ -86,6 +86,9 @@ ApplicationWindow { property var planMasterControllerPlanView: null property var currentPlanMissionItem: planMasterControllerPlanView ? planMasterControllerPlanView.missionController.currentPlanViewItem : null + + // Property to manage RemoteID quick acces to settings page + property bool commingFromRIDIndicator: false } /// Default color palette used throughout the UI diff --git a/src/ui/preferences/GeneralSettings.qml b/src/ui/preferences/GeneralSettings.qml index e915c58..82c7d5b 100644 --- a/src/ui/preferences/GeneralSettings.qml +++ b/src/ui/preferences/GeneralSettings.qml @@ -652,6 +652,14 @@ Rectangle { } } } + + // Check box to show/hide Remote ID submenu in App settings + FactCheckBox { + text: qsTr("Enable Remote ID") + fact: _remoteIDEnable + visible: _remoteIDEnable.visible + property Fact _remoteIDEnable: QGroundControl.settingsManager.remoteIDSettings.enable + } } } diff --git a/src/ui/preferences/RemoteIDSettings.qml b/src/ui/preferences/RemoteIDSettings.qml new file mode 100644 index 0000000..79ec86d --- /dev/null +++ b/src/ui/preferences/RemoteIDSettings.qml @@ -0,0 +1,916 @@ +/**************************************************************************** + * + * (c) 2009-2022 QGROUNDCONTROL PROJECT + * + * QGroundControl is licensed according to the terms in the file + * COPYING.md in the root of the source code directory. + * + ****************************************************************************/ + +import QtQuick 2.3 +import QtQuick.Controls 1.2 +import QtQuick.Controls.Styles 1.4 +import QtQuick.Dialogs 1.2 +import QtQuick.Layouts 1.2 + +import QGroundControl 1.0 +import QGroundControl.FactSystem 1.0 +import QGroundControl.FactControls 1.0 +import QGroundControl.Controls 1.0 +import QGroundControl.ScreenTools 1.0 +import QGroundControl.MultiVehicleManager 1.0 +import QGroundControl.Palette 1.0 + +Rectangle { + id: remoteIDRoot + color: qgcPal.window + anchors.fill: parent + + // Visual properties + property real _margins: ScreenTools.defaultFontPixelWidth + property real _labelWidth: ScreenTools.defaultFontPixelWidth * 28 + property real _valueWidth: ScreenTools.defaultFontPixelWidth * 24 + property real _columnSpacing: ScreenTools.defaultFontPixelHeight * 0.25 + property real _comboFieldWidth: ScreenTools.defaultFontPixelWidth * 30 + property real _valueFieldWidth: ScreenTools.defaultFontPixelWidth * 10 + property int _borderWidth: 3 + // Flags visual properties + property real flagsWidth: ScreenTools.defaultFontPixelWidth * 15 + property real flagsHeight: ScreenTools.defaultFontPixelWidth * 7 + property int radiusFlags: 5 + + // Flag to get active vehicle and active RID + property var _activeRID: _activeVehicle && _activeVehicle.remoteIDManager ? _activeVehicle.remoteIDManager : null + + // General properties + property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle + property int _regionOperation: QGroundControl.settingsManager.remoteIDSettings.region.value + property int _locationType: QGroundControl.settingsManager.remoteIDSettings.locationType.value + property int _classificationType: QGroundControl.settingsManager.remoteIDSettings.classificationType.value + + enum RegionOperation { + FAA, + EU + } + + enum LocationType { + TAKEOFF, + LIVE, + FIXED + } + + enum ClassificationType { + UNDEFINED, + EU + } + + // GPS properties + property var gcsPosition: QGroundControl.qgcPositionManger.gcsPosition + property real gcsHeading: QGroundControl.qgcPositionManger.gcsHeading + property real gcsHDOP: QGroundControl.qgcPositionManger.gcsPositionHorizontalAccuracy + property string gpsDisabled: "Disabled" + property string gpsUdpPort: "UDP Port" + + QGCPalette { id: qgcPal } + + // Function to get the corresponding Self ID label depending on the Self ID Type selected + function getSelfIdLabelText() { + switch (selfIDComboBox.currentIndex) { + case 0: + return QGroundControl.settingsManager.remoteIDSettings.selfIDFree.shortDescription + break + case 1: + return QGroundControl.settingsManager.remoteIDSettings.selfIDEmergency.shortDescription + break + case 2: + return QGroundControl.settingsManager.remoteIDSettings.selfIDExtended.shortDescription + break + default: + return QGroundControl.settingsManager.remoteIDSettings.selfIDFree.shortDescription + } + } + + // Function to get the corresponding Self ID fact depending on the Self ID Type selected + function getSelfIDFact() { + switch (selfIDComboBox.currentIndex) { + case 0: + return QGroundControl.settingsManager.remoteIDSettings.selfIDFree + break + case 1: + return QGroundControl.settingsManager.remoteIDSettings.selfIDEmergency + break + case 2: + return QGroundControl.settingsManager.remoteIDSettings.selfIDExtended + break + default: + return QGroundControl.settingsManager.remoteIDSettings.selfIDFree + } + } + + // Function to move flickable to desire position + function getFlickableToPosition(y) { + flicakbleRID.contentY = y + } + + Item { + id: flagsItem + anchors.top: parent.top + anchors.horizontalCenter: parent.horizontalCenter + anchors.horizontalCenterOffset: ScreenTools.defaultFontPixelWidth // Need this to account for the slight offset in the flickable + width: flicakbleRID.innerWidth + height: flagsColumn.height + + ColumnLayout { + id: flagsColumn + anchors.horizontalCenter: parent.horizontalCenter + spacing: _margins + + // ---------------------------------------- STATUS ----------------------------------------- + // Status flags. Visual representation for the state of all necesary information for remoteID + // to work propely. + Rectangle { + id: flagsRectangle + Layout.preferredHeight: statusGrid.height + (_margins * 2) + Layout.preferredWidth: statusGrid.width + (_margins * 2) + color: qgcPal.windowShade + visible: _activeVehicle + Layout.fillWidth: true + + GridLayout { + id: statusGrid + anchors.margins: _margins + anchors.top: parent.top + anchors.horizontalCenter: parent.horizontalCenter + rows: 1 + rowSpacing: _margins * 3 + columnSpacing: _margins * 2 + + Rectangle { + id: armFlag + Layout.preferredHeight: flagsHeight + Layout.preferredWidth: flagsWidth + color: _activeRID ? (_activeVehicle.remoteIDManager.armStatusGood ? qgcPal.colorGreen : qgcPal.colorRed) : qgcPal.colorGrey + radius: radiusFlags + + QGCLabel { + anchors.fill: parent + text: qsTr("ARM STATUS") + wrapMode: Text.WordWrap + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + font.bold: true + } + + // On clikced we go to the corresponding settings + MouseArea { + anchors.fill: parent + onClicked: getFlickableToPosition(flicakbleRID.armstatusY) + } + + } + + Rectangle { + id: commsFlag + Layout.preferredHeight: flagsHeight + Layout.preferredWidth: flagsWidth + color: _activeRID ? (_activeVehicle.remoteIDManager.commsGood ? qgcPal.colorGreen : qgcPal.colorRed) : qgcPal.colorGrey + radius: radiusFlags + + QGCLabel { + anchors.fill: parent + text: qsTr("RID COMMS") + wrapMode: Text.WordWrap + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + font.bold: true + } + } + + Rectangle { + id: gpsFlag + Layout.preferredHeight: flagsHeight + Layout.preferredWidth: flagsWidth + color: _activeRID ? (_activeVehicle.remoteIDManager.gcsGPSGood ? qgcPal.colorGreen : qgcPal.colorRed) : qgcPal.colorGrey + radius: radiusFlags + + QGCLabel { + anchors.fill: parent + text: qsTr("GCS GPS") + wrapMode: Text.WordWrap + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + font.bold: true + } + + // On clikced we go to the corresponding settings + MouseArea { + anchors.fill: parent + onClicked: getFlickableToPosition(flicakbleRID.gpsY) + } + } + + Rectangle { + id: basicIDFlag + Layout.preferredHeight: flagsHeight + Layout.preferredWidth: flagsWidth + color: _activeRID ? (_activeVehicle.remoteIDManager.basicIDGood ? qgcPal.colorGreen : qgcPal.colorRed) : qgcPal.colorGrey + radius: radiusFlags + + QGCLabel { + anchors.fill: parent + text: qsTr("BASIC ID") + wrapMode: Text.WordWrap + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + font.bold: true + } + + // On clikced we go to the corresponding settings + MouseArea { + anchors.fill: parent + onClicked: getFlickableToPosition(flicakbleRID.basicIDY) + } + } + + Rectangle { + id: operaotrIDFlag + Layout.preferredHeight: flagsHeight + Layout.preferredWidth: flagsWidth + color: _activeRID ? (_activeVehicle.remoteIDManager.operatorIDGood ? qgcPal.colorGreen : qgcPal.colorRed) : qgcPal.colorGrey + radius: radiusFlags + visible: _activeRID ? (QGroundControl.settingsManager.remoteIDSettings.sendOperatorID.value || _regionOperation == RemoteIDSettings.RegionOperation.EU) : false + + QGCLabel { + anchors.fill: parent + text: qsTr("OPERATOR ID") + wrapMode: Text.WordWrap + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + font.bold: true + } + + // On clicked we go to the corresponding settings + MouseArea { + anchors.fill: parent + onClicked: getFlickableToPosition(flicakbleRID.operatorIDY) + } + } + } + } + } + } + + QGCFlickable { + id: flicakbleRID + clip: true + anchors.top: flagsItem.visible ? flagsItem.bottom : parent.top + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + anchors.margins: ScreenTools.defaultFontPixelWidth + contentHeight: outerItem.height + contentWidth: outerItem.width + flickableDirection: Flickable.VerticalFlick + + property var innerWidth: settingsItem.width + + // Properties to position flickable + property var armstatusY: armStatusLabel.y + property var gpsY: gpsLabel.y + property var basicIDY: basicIDLabel.y + property var operatorIDY: operatorIDLabel.y + + Item { + id: outerItem + width: Math.max(remoteIDRoot.width, settingsItem.width) + height: settingsItem.height + + ColumnLayout { + id: settingsItem + anchors.horizontalCenter: parent.horizontalCenter + spacing: _margins + + // ----------------------------------------------------------------------------------------- + // ---------------------------------------- ARM STATUS ----------------------------------------- + // Arm status error + QGCLabel { + id: armStatusLabel + text: qsTr("ARM STATUS") + Layout.alignment: Qt.AlignHCenter + font.pointSize: ScreenTools.mediumFontPointSize + visible: _activeVehicle && !_activeVehicle.remoteIDManager.armStatusGood + } + + Rectangle { + id: armStatusRectangle + Layout.preferredHeight: armStatusGrid.height + (_margins * 2) + Layout.preferredWidth: armStatusGrid.width + (_margins * 2) + color: qgcPal.windowShade + Layout.fillWidth: true + border.width: _borderWidth + border.color: _activeRID ? (_activeVehicle.remoteIDManager.armStatusGood ? color : qgcPal.colorRed) : color + + visible: _activeVehicle && !_activeVehicle.remoteIDManager.armStatusGood + + GridLayout { + id: armStatusGrid + anchors.margins: _margins + anchors.top: parent.top + anchors.horizontalCenter: parent.horizontalCenter + columns: 2 + rowSpacing: _margins * 3 + columnSpacing: _margins * 2 + + QGCLabel { + text: qsTr("Arm status error: ") + Layout.fillWidth: true + } + QGCLabel { + text: _activeVehicle ? _activeVehicle.remoteIDManager.armStatusError : "" + Layout.fillWidth: true + } + } + } + // ----------------------------------------------------------------------------------------- + + // ---------------------------------------- REGION ----------------------------------------- + // Region of operation to accomodate for different requirements + QGCLabel { + id: regionLabel + text: qsTr("Region") + Layout.alignment: Qt.AlignHCenter + font.pointSize: ScreenTools.mediumFontPointSize + } + + Rectangle { + id: regionRectangle + Layout.preferredHeight: regionGrid.height + (_margins * 2) + Layout.preferredWidth: regionGrid.width + (_margins * 2) + color: qgcPal.windowShade + visible: true + Layout.fillWidth: true + + GridLayout { + id: regionGrid + anchors.margins: _margins + anchors.top: parent.top + anchors.horizontalCenter: parent.horizontalCenter + columns: 2 + rowSpacing: _margins * 3 + columnSpacing: _margins * 2 + + QGCLabel { + text: QGroundControl.settingsManager.remoteIDSettings.region.shortDescription + visible: QGroundControl.settingsManager.remoteIDSettings.region.visible + Layout.fillWidth: true + } + FactComboBox { + fact: QGroundControl.settingsManager.remoteIDSettings.region + visible: QGroundControl.settingsManager.remoteIDSettings.region.visible + Layout.fillWidth: true + sizeToContents: true + // In case we change from EU to FAA having the location Type to FIXED, since its not supported in FAA + // we need to change it to Live GNSS + onActivated: { + if (currentIndex == RemoteIDSettings.RegionOperation.FAA && QGroundControl.settingsManager.remoteIDSettings.locationType.value != RemoteIDSettings.LocationType.LIVE) + QGroundControl.settingsManager.remoteIDSettings.locationType.value = RemoteIDSettings.LocationType.LIVE + } + } + + QGCLabel { + text: QGroundControl.settingsManager.remoteIDSettings.classificationType.shortDescription + visible: _regionOperation == RemoteIDSettings.RegionOperation.EU + Layout.fillWidth: true + } + FactComboBox { + fact: QGroundControl.settingsManager.remoteIDSettings.classificationType + visible: _regionOperation == RemoteIDSettings.RegionOperation.EU + Layout.fillWidth: true + sizeToContents: true + } + + QGCLabel { + text: QGroundControl.settingsManager.remoteIDSettings.categoryEU.shortDescription + visible: (_classificationType == RemoteIDSettings.ClassificationType.EU) && (_regionOperation == RemoteIDSettings.RegionOperation.EU) + Layout.fillWidth: true + } + FactComboBox { + fact: QGroundControl.settingsManager.remoteIDSettings.categoryEU + visible: (_classificationType == RemoteIDSettings.ClassificationType.EU) && (_regionOperation == RemoteIDSettings.RegionOperation.EU) + Layout.fillWidth: true + sizeToContents: true + } + + QGCLabel { + text: QGroundControl.settingsManager.remoteIDSettings.classEU.shortDescription + visible: (_classificationType == RemoteIDSettings.ClassificationType.EU) && (_regionOperation == RemoteIDSettings.RegionOperation.EU) + Layout.fillWidth: true + } + FactComboBox { + fact: QGroundControl.settingsManager.remoteIDSettings.classEU + visible: (_classificationType == RemoteIDSettings.ClassificationType.EU) && (_regionOperation == RemoteIDSettings.RegionOperation.EU) + Layout.fillWidth: true + sizeToContents: true + } + } + } + // ----------------------------------------------------------------------------------------- + + // ----------------------------------------- GPS ------------------------------------------- + // Data representation and connection options for GCS GPS. + QGCLabel { + id: gpsLabel + text: qsTr("GPS GCS") + Layout.alignment: Qt.AlignHCenter + font.pointSize: ScreenTools.mediumFontPointSize + } + + Rectangle { + id: gpsRectangle + Layout.preferredHeight: gpsGrid.height + gpsGridData.height + (_margins * 3) + Layout.preferredWidth: gpsGrid.width + (_margins * 2) + color: qgcPal.windowShade + visible: true + Layout.fillWidth: true + + border.width: _borderWidth + border.color: _activeRID ? (_activeVehicle.remoteIDManager.gcsGPSGood ? color : qgcPal.colorRed) : color + + property var locationTypeValue: QGroundControl.settingsManager.remoteIDSettings.locationType.value + + // In case we change from FAA to EU region, having selected Location Type FIXED, + // We have to change the currentindex to the locationType forced when we change region + onLocationTypeValueChanged: { + if (locationTypeComboBox.currentIndex != locationTypeValue) { + locationTypeComboBox.currentIndex = locationTypeValue + } + } + + GridLayout { + id: gpsGridData + anchors.margins: _margins + anchors.top: parent.top + anchors.horizontalCenter: parent.horizontalCenter + rowSpacing: _margins + columns: 2 + columnSpacing: _margins * 2 + + QGCLabel { + text: QGroundControl.settingsManager.remoteIDSettings.locationType.shortDescription + visible: QGroundControl.settingsManager.remoteIDSettings.locationType.visible + Layout.fillWidth: true + } + FactComboBox { + id: locationTypeComboBox + fact: QGroundControl.settingsManager.remoteIDSettings.locationType + visible: QGroundControl.settingsManager.remoteIDSettings.locationType.visible + Layout.fillWidth: true + sizeToContents: true + + onActivated: { + // FAA doesnt allow to set a Fixed position. Is either Live GNSS or Takeoff + if (_regionOperation == RemoteIDSettings.RegionOperation.FAA) { + if (currentIndex != 1) { + QGroundControl.settingsManager.remoteIDSettings.locationType.value = 1 + currentIndex = 1 + } + } else { + // TODO: this lines below efectively disable TAKEOFF option. Uncoment when we add support for it + if (currentIndex == 0) { + QGroundControl.settingsManager.remoteIDSettings.locationType.value = 1 + currentIndex = 1 + } else { + QGroundControl.settingsManager.remoteIDSettings.locationType.value = index + currentIndex = index + } + // -------------------------------------------------------------------------------------------------- + } + } + } + + QGCLabel { + text: qsTr("Latitude Fixed(-90 to 90)") + visible: _locationType == RemoteIDSettings.LocationType.FIXED + Layout.fillWidth: true + } + FactTextField { + visible: _locationType == RemoteIDSettings.LocationType.FIXED + Layout.fillWidth: true + fact: QGroundControl.settingsManager.remoteIDSettings.latitudeFixed + } + + QGCLabel { + text: qsTr("Longitude Fixed(-180 to 180)") + visible: _locationType == RemoteIDSettings.LocationType.FIXED + Layout.fillWidth: true + } + FactTextField { + visible: _locationType == RemoteIDSettings.LocationType.FIXED + Layout.fillWidth: true + fact: QGroundControl.settingsManager.remoteIDSettings.longitudeFixed + } + + QGCLabel { + text: qsTr("Altitude Fixed") + visible: _locationType == RemoteIDSettings.LocationType.FIXED + Layout.fillWidth: true + } + FactTextField { + visible: _locationType == RemoteIDSettings.LocationType.FIXED + Layout.fillWidth: true + fact: QGroundControl.settingsManager.remoteIDSettings.altitudeFixed + } + + QGCLabel { + text: qsTr("Latitude") + Layout.fillWidth: true + visible: _locationType != RemoteIDSettings.LocationType.TAKEOFF + } + QGCLabel { + text: gcsPosition.isValid ? gcsPosition.latitude : "N/A" + Layout.fillWidth: true + visible: _locationType != RemoteIDSettings.LocationType.TAKEOFF + } + + QGCLabel { + text: qsTr("Longitude") + Layout.fillWidth: true + visible: _locationType != RemoteIDSettings.LocationType.TAKEOFF + } + QGCLabel { + text: gcsPosition.isValid ? gcsPosition.longitude : "N/A" + Layout.fillWidth: true + visible: _locationType != RemoteIDSettings.LocationType.TAKEOFF + } + + QGCLabel { + text: _regionOperation == RemoteIDSettings.RegionOperation.FAA ? + qsTr("Altitude") + qsTr(" (Mandatory)") : + qsTr("Altitude") + Layout.fillWidth: true + visible: _locationType != RemoteIDSettings.LocationType.TAKEOFF + } + QGCLabel { + text: gcsPosition.isValid && !isNaN(gcsPosition.altitude) ? gcsPosition.altitude : "N/A" + Layout.fillWidth: true + visible: _locationType != RemoteIDSettings.LocationType.TAKEOFF + } + + QGCLabel { + text: qsTr("Heading") + Layout.fillWidth: true + visible: _locationType != RemoteIDSettings.LocationType.TAKEOFF + } + QGCLabel { + text: gcsPosition.isValid && !isNaN(gcsHeading) ? gcsHeading : "N/A" + Layout.fillWidth: true + visible: _locationType != RemoteIDSettings.LocationType.TAKEOFF + } + + QGCLabel { + text: qsTr("Hor. Accuracy") + Layout.fillWidth: true + visible: _locationType != RemoteIDSettings.LocationType.TAKEOFF + } + QGCLabel { + text: gcsPosition.isValid && gcsHDOP ? ( gcsHDOP + " m" ) : "N/A" + Layout.fillWidth: true + visible: _locationType != RemoteIDSettings.LocationType.TAKEOFF + } + } + + GridLayout { + id: gpsGrid + visible: !ScreenTools.isMobile + && QGroundControl.settingsManager.autoConnectSettings.autoConnectNmeaPort.visible + && QGroundControl.settingsManager.autoConnectSettings.autoConnectNmeaBaud.visible + && _locationType != RemoteIDSettings.LocationType.TAKEOFF + anchors.margins: _margins + anchors.top: gpsGridData.bottom + anchors.horizontalCenter: parent.horizontalCenter + rowSpacing: _margins * 3 + columns: 2 + columnSpacing: _margins * 2 + + QGCLabel { + text: qsTr("NMEA External GPS Device") + } + QGCComboBox { + id: nmeaPortCombo + Layout.preferredWidth: _comboFieldWidth + + model: ListModel { + } + + onActivated: { + if (index != -1) { + QGroundControl.settingsManager.autoConnectSettings.autoConnectNmeaPort.value = textAt(index); + } + } + Component.onCompleted: { + model.append({text: gpsDisabled}) + model.append({text: gpsUdpPort}) + + for (var i in QGroundControl.linkManager.serialPorts) { + nmeaPortCombo.model.append({text:QGroundControl.linkManager.serialPorts[i]}) + } + var index = nmeaPortCombo.find(QGroundControl.settingsManager.autoConnectSettings.autoConnectNmeaPort.valueString); + nmeaPortCombo.currentIndex = index; + if (QGroundControl.linkManager.serialPorts.length === 0) { + nmeaPortCombo.model.append({text: "Serial "}) + } + } + } + + QGCLabel { + visible: nmeaPortCombo.currentText !== gpsUdpPort && nmeaPortCombo.currentText !== gpsDisabled + text: qsTr("NMEA GPS Baudrate") + } + QGCComboBox { + visible: nmeaPortCombo.currentText !== gpsUdpPort && nmeaPortCombo.currentText !== gpsDisabled + id: nmeaBaudCombo + Layout.preferredWidth: _comboFieldWidth + model: [1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600] + + onActivated: { + if (index != -1) { + QGroundControl.settingsManager.autoConnectSettings.autoConnectNmeaBaud.value = textAt(index); + } + } + Component.onCompleted: { + var index = nmeaBaudCombo.find(QGroundControl.settingsManager.autoConnectSettings.autoConnectNmeaBaud.valueString); + nmeaBaudCombo.currentIndex = index; + } + } + + QGCLabel { + text: qsTr("NMEA stream UDP port") + visible: nmeaPortCombo.currentText === gpsUdpPort + } + FactTextField { + visible: nmeaPortCombo.currentText === gpsUdpPort + Layout.preferredWidth: _valueFieldWidth + fact: QGroundControl.settingsManager.autoConnectSettings.nmeaUdpPort + } + } + } + // ----------------------------------------------------------------------------------------- + + // -------------------------------------- BASIC ID ------------------------------------------- + QGCLabel { + id: basicIDLabel + text: qsTr("BASIC ID") + Layout.alignment: Qt.AlignHCenter + font.pointSize: ScreenTools.mediumFontPointSize + } + + Rectangle { + id: basicIDRectangle + Layout.preferredHeight: basicIDGrid.height + basicIDnote.height + (_margins * 4) + Layout.preferredWidth: basicIDGrid.width + basicIDnote.width + (_margins * 2) + color: qgcPal.windowShade + Layout.fillWidth: true + + border.width: _borderWidth + border.color: _activeRID ? (_activeVehicle.remoteIDManager.basicIDGood ? color : qgcPal.colorRed) : color + + QGCLabel { + id: basicIDnote + anchors.margins: _margins + anchors.top: parent.top + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottomMargin: _margins * 2 + width: basicIDGrid.width + text: qsTr("Note: This parameter is optional if Basic ID is already set on RID device. " + + "On that case, this one will be registered as Basic ID 2") + wrapMode: Text.Wrap + visible: QGroundControl.settingsManager.remoteIDSettings.basicIDType.visible + + } + + GridLayout { + id: basicIDGrid + anchors.margins: _margins + anchors.top: basicIDnote.bottom + anchors.horizontalCenter: parent.horizontalCenter + columns: 2 + rowSpacing: _margins * 3 + columnSpacing: _margins * 2 + + QGCLabel { + text: QGroundControl.settingsManager.remoteIDSettings.basicIDType.shortDescription + visible: QGroundControl.settingsManager.remoteIDSettings.basicIDType.visible + Layout.fillWidth: true + } + FactComboBox { + fact: QGroundControl.settingsManager.remoteIDSettings.basicIDType + visible: QGroundControl.settingsManager.remoteIDSettings.basicIDType.visible + Layout.fillWidth: true + sizeToContents: true + } + + QGCLabel { + text: QGroundControl.settingsManager.remoteIDSettings.basicIDUaType.shortDescription + visible: QGroundControl.settingsManager.remoteIDSettings.basicIDUaType.visible + Layout.fillWidth: true + } + FactComboBox { + fact: QGroundControl.settingsManager.remoteIDSettings.basicIDUaType + visible: QGroundControl.settingsManager.remoteIDSettings.basicIDUaType.visible + Layout.fillWidth: true + sizeToContents: true + } + + QGCLabel { + text: _activeRID && _activeVehicle.remoteIDManager.basicIDGood ? + QGroundControl.settingsManager.remoteIDSettings.basicID.shortDescription : + QGroundControl.settingsManager.remoteIDSettings.basicID.shortDescription + qsTr(" (Mandatory)") + visible: QGroundControl.settingsManager.remoteIDSettings.basicID.visible + Layout.alignment: Qt.AlignHCenter + Layout.fillWidth: true + } + FactTextField { + fact: QGroundControl.settingsManager.remoteIDSettings.basicID + visible: QGroundControl.settingsManager.remoteIDSettings.basicID.visible + Layout.fillWidth: true + } + + QGCLabel { + text: QGroundControl.settingsManager.remoteIDSettings.sendBasicID.shortDescription + Layout.fillWidth: true + visible: QGroundControl.settingsManager.remoteIDSettings.basicID.visible + } + FactCheckBox { + fact: QGroundControl.settingsManager.remoteIDSettings.sendBasicID + visible: QGroundControl.settingsManager.remoteIDSettings.basicID.visible + } + } + } + // ------------------------------------------------------------------------------------------ + + // ------------------------------------ OPERATOR ID ---------------------------------------- + QGCLabel { + id: operatorIDLabel + text: qsTr("Operator ID") + Layout.alignment: Qt.AlignHCenter + font.pointSize: ScreenTools.mediumFontPointSize + } + + Rectangle { + id: operatorIDRectangle + Layout.preferredHeight: operatorIDGrid.height + (_margins * 3) + Layout.preferredWidth: operatorIDGrid.width + (_margins * 2) + color: qgcPal.windowShade + Layout.fillWidth: true + + border.width: _borderWidth + border.color: (_regionOperation == RemoteIDSettings.RegionOperation.EU || QGroundControl.settingsManager.remoteIDSettings.sendOperatorID.value) ? + (_activeRID && !_activeVehicle.remoteIDManager.operatorIDGood ? qgcPal.colorRed : color) : color + + GridLayout { + id: operatorIDGrid + anchors.margins: _margins + anchors.top: parent.top + anchors.horizontalCenter: parent.horizontalCenter + columns: 2 + rowSpacing: _margins * 3 + columnSpacing: _margins * 2 + + QGCLabel { + text: QGroundControl.settingsManager.remoteIDSettings.operatorIDType.shortDescription + visible: QGroundControl.settingsManager.remoteIDSettings.operatorIDType.visible + Layout.fillWidth: true + } + FactComboBox { + id: operatorIDFactComboBox + fact: QGroundControl.settingsManager.remoteIDSettings.operatorIDType + visible: QGroundControl.settingsManager.remoteIDSettings.operatorIDType.visible && (QGroundControl.settingsManager.remoteIDSettings.operatorIDType.enumValues.length > 1) + Layout.fillWidth: true + sizeToContents: true + } + QGCLabel{ + text: QGroundControl.settingsManager.remoteIDSettings.operatorIDType.enumStringValue + visible: !operatorIDFactComboBox.visible + Layout.fillWidth: true + } + + QGCLabel { + text: _regionOperation == RemoteIDSettings.RegionOperation.FAA ? + QGroundControl.settingsManager.remoteIDSettings.operatorID.shortDescription : + QGroundControl.settingsManager.remoteIDSettings.operatorID.shortDescription + qsTr(" (Mandatory)") + visible: QGroundControl.settingsManager.remoteIDSettings.operatorID.visible + Layout.alignment: Qt.AlignHCenter + Layout.fillWidth: true + } + FactTextField { + id: operatorIDTextField + fact: QGroundControl.settingsManager.remoteIDSettings.operatorID + visible: QGroundControl.settingsManager.remoteIDSettings.operatorID.visible + Layout.fillWidth: true + maximumLength: 20 // Maximum defined by Mavlink definition of OPEN_DRONE_ID_OPERATOR_ID message + onEditingFinished: { + if (_activeVehicle) { + _activeVehicle.remoteIDManager.checkOperatorID() + } + } + + } + + QGCLabel { + text: QGroundControl.settingsManager.remoteIDSettings.sendOperatorID.shortDescription + Layout.fillWidth: true + visible: _regionOperation == RemoteIDSettings.RegionOperation.FAA + } + FactCheckBox { + fact: QGroundControl.settingsManager.remoteIDSettings.sendOperatorID + visible: _regionOperation == RemoteIDSettings.RegionOperation.FAA + onClicked: { + if (checked) { + if (_activeVehicle) { + _activeVehicle.remoteIDManager.checkOperatorID() + } + } + } + } + } + } + // ----------------------------------------------------------------------------------------- + + // -------------------------------------- SELF ID ------------------------------------------ + QGCLabel { + id: selfIDLabel + text: qsTr("Self ID") + Layout.alignment: Qt.AlignHCenter + font.pointSize: ScreenTools.mediumFontPointSize + } + + Rectangle { + id: selfIDRectangle + Layout.preferredHeight: selfIDGrid.height + selfIDnote.height + (_margins * 3) + Layout.preferredWidth: selfIDGrid.width + (_margins * 2) + color: qgcPal.windowShade + visible: true + Layout.fillWidth: true + + GridLayout { + id: selfIDGrid + anchors.margins: _margins + anchors.top: parent.top + anchors.horizontalCenter: parent.horizontalCenter + columns: 2 + rowSpacing: _margins * 3 + columnSpacing: _margins * 2 + + QGCLabel { + text: QGroundControl.settingsManager.remoteIDSettings.selfIDType.shortDescription + visible: QGroundControl.settingsManager.remoteIDSettings.selfIDType.visible + Layout.fillWidth: true + } + FactComboBox { + id: selfIDComboBox + fact: QGroundControl.settingsManager.remoteIDSettings.selfIDType + visible: QGroundControl.settingsManager.remoteIDSettings.selfIDType.visible + Layout.fillWidth: true + sizeToContents: true + } + + QGCLabel { + text: getSelfIdLabelText() + Layout.fillWidth: true + } + FactTextField { + fact: getSelfIDFact() + Layout.fillWidth: true + maximumLength: 23 // Maximum defined by Mavlink definition of OPEN_DRONE_ID_SELF_ID message + } + + QGCLabel { + text: QGroundControl.settingsManager.remoteIDSettings.sendSelfID.shortDescription + Layout.fillWidth: true + } + FactCheckBox { + fact: QGroundControl.settingsManager.remoteIDSettings.sendSelfID + visible: QGroundControl.settingsManager.remoteIDSettings.sendSelfID.visible + } + } + + QGCLabel { + id: selfIDnote + width: selfIDGrid.width + anchors.margins: _margins + anchors.top: selfIDGrid.bottom + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottomMargin: _margins * 2 + text: qsTr("Note: Even if this box is unset, QGroundControl will send self ID message " + + "if an emergency is set, or after it has been cleared. \ + The message for each kind of selfID is saved and preserves reboots. Select " + + "each type on the Self ID type dropdown to configure the message to be sent") + wrapMode: Text.Wrap + visible: QGroundControl.settingsManager.remoteIDSettings.selfIDType.visible + } + } + // ----------------------------------------------------------------------------------------- + } + } + } +} diff --git a/src/ui/toolbar/RemoteIDIndicator.qml b/src/ui/toolbar/RemoteIDIndicator.qml new file mode 100644 index 0000000..b3d4a54 --- /dev/null +++ b/src/ui/toolbar/RemoteIDIndicator.qml @@ -0,0 +1,355 @@ +/**************************************************************************** + * + * (c) 2009-2022 QGROUNDCONTROL PROJECT + * + * QGroundControl is licensed according to the terms in the file + * COPYING.md in the root of the source code directory. + * + ****************************************************************************/ + +import QtQuick 2.11 +import QtQuick.Layouts 1.11 + +import QGroundControl 1.0 +import QGroundControl.Controls 1.0 +import QGroundControl.MultiVehicleManager 1.0 +import QGroundControl.ScreenTools 1.0 +import QGroundControl.Palette 1.0 + +//------------------------------------------------------------------------- +//-- Remote ID Indicator +Item { + id: _root + width: remoteIDIcon.width * 1.1 + anchors.top: parent.top + anchors.bottom: parent.bottom + + property bool showIndicator: QGroundControl.settingsManager.remoteIDSettings.enable.value + + property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle + property int remoteIDState: getRemoteIDState() + + property bool gpsFlag: _activeVehicle && _activeVehicle.remoteIDManager ? _activeVehicle.remoteIDManager.gcsGPSGood : false + property bool basicIDFlag: _activeVehicle && _activeVehicle.remoteIDManager ? _activeVehicle.remoteIDManager.basicIDGood : false + property bool armFlag: _activeVehicle && _activeVehicle.remoteIDManager ? _activeVehicle.remoteIDManager.armStatusGood : false + property bool commsFlag: _activeVehicle && _activeVehicle.remoteIDManager ? _activeVehicle.remoteIDManager.commsGood : false + property bool emergencyDeclared: _activeVehicle && _activeVehicle.remoteIDManager ? _activeVehicle.remoteIDManager.emergencyDeclared : false + property bool operatorIDFlag: _activeVehicle && _activeVehicle.remoteIDManager ? _activeVehicle.remoteIDManager.operatorIDGood : false + + property int _regionOperation: QGroundControl.settingsManager.remoteIDSettings.region.value + + // Flags visual properties + property real flagsWidth: ScreenTools.defaultFontPixelWidth * 10 + property real flagsHeight: ScreenTools.defaultFontPixelWidth * 5 + property int radiusFlags: 5 + + // Visual properties + property real _margins: ScreenTools.defaultFontPixelWidth + + enum RIDState { + HEALTHY, + WARNING, + ERROR, + UNAVAILABLE + } + + enum RegionOperation { + FAA, + EU + } + + function getRIDIcon() { + switch (remoteIDState) { + case RemoteIDIndicator.RIDState.HEALTHY: + return "/qmlimages/RidIconGreen.svg" + break + case RemoteIDIndicator.RIDState.WARNING: + return "/qmlimages/RidIconYellow.svg" + break + case RemoteIDIndicator.RIDState.ERROR: + return "/qmlimages/RidIconRed.svg" + break + case RemoteIDIndicator.RIDState.UNAVAILABLE: + return "/qmlimages/RidIconGrey.svg" + break + default: + return "/qmlimages/RidIconGrey.svg" + } + } + + function getRemoteIDState() { + if (!_activeVehicle) { + return RemoteIDIndicator.RIDState.UNAVAILABLE + } + // We need to have comms and arm healthy to even be in any other state other than ERROR + if (!commsFlag || !armFlag || emergencyDeclared) { + return RemoteIDIndicator.RIDState.ERROR + } + if (!gpsFlag || !basicIDFlag) { + return RemoteIDIndicator.RIDState.WARNING + } + if (_regionOperation == RemoteIDIndicator.RegionOperation.EU || QGroundControl.settingsManager.remoteIDSettings.sendOperatorID.value) { + if (!operatorIDFlag) { + return RemoteIDIndicator.RIDState.WARNING + } + } + return RemoteIDIndicator.RIDState.HEALTHY + } + + function goToSettings() { + if (!mainWindow.preventViewSwitch()) { + globals.commingFromRIDIndicator = true + mainWindow.showSettingsTool() + } + } + + Component { + id: remoteIDInfo + + Rectangle { + width: remoteIDCol.width + ScreenTools.defaultFontPixelWidth * 3 + height: remoteIDCol.height + ScreenTools.defaultFontPixelHeight * 2 + (emergencyButtonItem.visible ? emergencyButtonItem.height : 0) + radius: ScreenTools.defaultFontPixelHeight * 0.5 + color: qgcPal.window + border.color: qgcPal.text + + Column { + id: remoteIDCol + spacing: ScreenTools.defaultFontPixelHeight * 0.5 + width: Math.max(remoteIDGrid.width, remoteIDLabel.width) + anchors.margins: ScreenTools.defaultFontPixelHeight + anchors.top: parent.top + anchors.horizontalCenter: parent.horizontalCenter + + QGCLabel { + id: remoteIDLabel + text: qsTr("RemoteID Status") + font.family: ScreenTools.demiboldFontFamily + anchors.horizontalCenter: parent.horizontalCenter + } + + GridLayout { + id: remoteIDGrid + anchors.margins: ScreenTools.defaultFontPixelHeight + columnSpacing: ScreenTools.defaultFontPixelWidth + anchors.horizontalCenter: parent.horizontalCenter + columns: 2 + + Image { + id: armFlagImage + width: flagsWidth + height: flagsHeight + source: armFlag ? "/qmlimages/RidFlagBackgroundGreen.svg" : "/qmlimages/RidFlagBackgroundRed.svg" + fillMode: Image.PreserveAspectFit + sourceSize.height: height + + QGCLabel { + anchors.fill: parent + text: qsTr("ARM STATUS") + wrapMode: Text.WordWrap + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + font.bold: true + font.pointSize: ScreenTools.smallFontPointSize + } + + QGCMouseArea { + anchors.fill: parent + onClicked: goToSettings() + } + } + + Image { + id: commsFlagImage + width: flagsWidth + height: flagsHeight + source: commsFlag ? "/qmlimages/RidFlagBackgroundGreen.svg" : "/qmlimages/RidFlagBackgroundRed.svg" + fillMode: Image.PreserveAspectFit + sourceSize.height: height + + QGCLabel { + anchors.fill: parent + text: qsTr("RID COMMS") + wrapMode: Text.WordWrap + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + font.bold: true + font.pointSize: ScreenTools.smallFontPointSize + } + + QGCMouseArea { + anchors.fill: parent + onClicked: goToSettings() + } + } + + Image { + id: gpsFlagImage + width: flagsWidth + height: flagsHeight + source: gpsFlag ? "/qmlimages/RidFlagBackgroundGreen.svg" : "/qmlimages/RidFlagBackgroundRed.svg" + fillMode: Image.PreserveAspectFit + sourceSize.height: height + + QGCLabel { + anchors.fill: parent + text: qsTr("GCS GPS") + wrapMode: Text.WordWrap + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + font.bold: true + font.pointSize: ScreenTools.smallFontPointSize + } + + QGCMouseArea { + anchors.fill: parent + onClicked: goToSettings() + } + } + + Image { + id: basicIDFlagIge + width: flagsWidth + height: flagsHeight + source: basicIDFlag ? "/qmlimages/RidFlagBackgroundGreen.svg" : "/qmlimages/RidFlagBackgroundRed.svg" + fillMode: Image.PreserveAspectFit + sourceSize.height: height + + QGCLabel { + anchors.fill: parent + text: qsTr("BASIC ID") + wrapMode: Text.WordWrap + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + font.bold: true + font.pointSize: ScreenTools.smallFontPointSize + } + + QGCMouseArea { + anchors.fill: parent + onClicked: goToSettings() + } + } + + Image { + id: operatorIDFlagImage + width: flagsWidth + height: flagsHeight + source: operatorIDFlag ? "/qmlimages/RidFlagBackgroundGreen.svg" : "/qmlimages/RidFlagBackgroundRed.svg" + fillMode: Image.PreserveAspectFit + sourceSize.height: height + visible: _activeVehicle ? (QGroundControl.settingsManager.remoteIDSettings.sendOperatorID.value || _regionOperation == RemoteIDIndicator.RegionOperation.EU) : false + + QGCLabel { + anchors.fill: parent + text: qsTr("OPERATOR ID") + wrapMode: Text.WordWrap + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + font.bold: true + font.pointSize: ScreenTools.smallFontPointSize + } + + QGCMouseArea { + anchors.fill: parent + onClicked: goToSettings() + } + } + } + } + + Item { + id: emergencyButtonItem + anchors.top: remoteIDCol.bottom + anchors.left: parent.left + anchors.right: parent.right + height: emergencyDeclareLabel.height + emergencyButton.height + (_margins * 4) + visible: commsFlag + + QGCLabel { + id: emergencyDeclareLabel + text: emergencyDeclared ? qsTr("EMERGENCY HAS BEEN DECLARED, Press and Hold for 3 seconds to cancel") : qsTr("Press and Hold below button to declare emergency") + font.family: ScreenTools.demiboldFontFamily + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + anchors.margins: _margins + anchors.topMargin: _margins * 3 + wrapMode: Text.WordWrap + horizontalAlignment: Text.AlignHCenter + visible: true + } + + Image { + id: emergencyButton + width: flagsWidth * 2 + height: flagsHeight * 1.5 + source: "/qmlimages/RidEmergencyBackground.svg" + sourceSize.height: height + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: emergencyDeclareLabel.bottom + anchors.margins: _margins + visible: true + + QGCLabel { + anchors.fill: parent + text: emergencyDeclared ? qsTr("Clear Emergency") : qsTr("EMERGENCY") + wrapMode: Text.WordWrap + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + font.bold: true + font.pointSize: ScreenTools.largeFontPointSize + } + + Timer { + id: emergencyButtonTimer + interval: 350 + onTriggered: { + if (emergencyButton.source == "/qmlimages/RidEmergencyBackgroundHighlight.svg" ) { + emergencyButton.source = "/qmlimages/RidEmergencyBackground.svg" + } else { + emergencyButton.source = "/qmlimages/RidEmergencyBackgroundHighlight.svg" + } + } + } + + MouseArea { + anchors.fill: parent + hoverEnabled: true + onEntered: emergencyButton.source = "/qmlimages/RidEmergencyBackgroundHighlight.svg" + onExited: emergencyButton.source = "/qmlimages/RidEmergencyBackground.svg" + pressAndHoldInterval: emergencyDeclared ? 3000 : 800 + onPressAndHold: { + if (emergencyButton.source == "/qmlimages/RidEmergencyBackgroundHighlight.svg" ) { + emergencyButton.source = "/qmlimages/RidEmergencyBackground.svg" + } else { + emergencyButton.source = "/qmlimages/RidEmergencyBackgroundHighlight.svg" + } + emergencyButtonTimer.restart() + if (_activeVehicle) { + _activeVehicle.remoteIDManager.setEmergency(!emergencyDeclared) + } + } + } + } + } + } + } + + Image { + id: remoteIDIcon + width: height + anchors.top: parent.top + anchors.bottom: parent.bottom + source: getRIDIcon() + fillMode: Image.PreserveAspectFit + sourceSize.height: height + } + + MouseArea { + anchors.fill: parent + onClicked: { + mainWindow.showIndicatorPopup(_root, remoteIDInfo) + } + } +}