/**************************************************************************** * * (c) 2009-2019 QGROUNDCONTROL PROJECT * * QGroundControl is licensed according to the terms in the file * COPYING.md in the root of the source code directory. * * @file * @author Gus Grubba */ import QtQuick 2.11 import QtQuick.Controls 2.4 import QtQuick.Layouts 1.11 import QtQuick.Dialogs 1.3 import QtPositioning 5.2 import QGroundControl 1.0 import QGroundControl.Controls 1.0 import QGroundControl.FlightMap 1.0 import QGroundControl.Palette 1.0 import QGroundControl.ScreenTools 1.0 import QGroundControl.Vehicle 1.0 import QGroundControl.QGCPositionManager 1.0 import Custom.Widgets 1.0 Item { anchors.fill: parent visible: !QGroundControl.videoManager.fullScreen readonly property string scaleState: "topMode" readonly property string noGPS: qsTr("NO GPS") readonly property real indicatorValueWidth: ScreenTools.defaultFontPixelWidth * 7 property real _indicatorDiameter: ScreenTools.defaultFontPixelWidth * 18 property real _indicatorsHeight: ScreenTools.defaultFontPixelHeight property var _sepColor: qgcPal.globalTheme === QGCPalette.Light ? Qt.rgba(0,0,0,0.5) : Qt.rgba(1,1,1,0.5) property color _indicatorsColor: qgcPal.text property bool _isVehicleGps: activeVehicle && activeVehicle.gps && activeVehicle.gps.count.rawValue > 1 && activeVehicle.gps.hdop.rawValue < 1.4 property string _altitude: activeVehicle ? (isNaN(activeVehicle.altitudeRelative.value) ? "0.0" : activeVehicle.altitudeRelative.value.toFixed(1)) + ' ' + activeVehicle.altitudeRelative.units : "0.0" property string _distanceStr: isNaN(_distance) ? "0" : _distance.toFixed(0) + ' ' + (activeVehicle ? activeVehicle.altitudeRelative.units : "") property real _heading: activeVehicle ? activeVehicle.heading.rawValue : 0 property real _distance: 0.0 property string _messageTitle: "" property string _messageText: "" function secondsToHHMMSS(timeS) { var sec_num = parseInt(timeS, 10); var hours = Math.floor(sec_num / 3600); var minutes = Math.floor((sec_num - (hours * 3600)) / 60); var seconds = sec_num - (hours * 3600) - (minutes * 60); if (hours < 10) {hours = "0"+hours;} if (minutes < 10) {minutes = "0"+minutes;} if (seconds < 10) {seconds = "0"+seconds;} return hours+':'+minutes+':'+seconds; } // FIXE: Isn't distance to home in factgroup Connections { target: QGroundControl.qgcPositionManger onGcsPositionChanged: { if (activeVehicle && gcsPosition.latitude && Math.abs(gcsPosition.latitude) > 0.001 && gcsPosition.longitude && Math.abs(gcsPosition.longitude) > 0.001) { var gcs = QtPositioning.coordinate(gcsPosition.latitude, gcsPosition.longitude) var veh = activeVehicle.coordinate; _distance = QGroundControl.unitsConversion.metersToAppSettingsHorizontalDistanceUnits(gcs.distanceTo(veh)); //-- Ignore absurd values if(_distance > 99999) _distance = 0; if(_distance < 0) _distance = 0; } else { _distance = 0; } } } //------------------------------------------------------------------------- //-- Heading Indicator Rectangle { id: compassBar height: ScreenTools.defaultFontPixelHeight * 1.5 width: ScreenTools.defaultFontPixelWidth * 50 color: "#DEDEDE" radius: 2 clip: true anchors.top: parent.top anchors.topMargin: ScreenTools.defaultFontPixelHeight anchors.horizontalCenter: parent.horizontalCenter visible: !mainIsMap Repeater { model: 720 visible: !mainIsMap QGCLabel { function _normalize(degrees) { var a = degrees % 360 if (a < 0) a += 360 return a } property int _startAngle: modelData + 180 + _heading property int _angle: _normalize(_startAngle) anchors.verticalCenter: parent.verticalCenter x: visible ? ((modelData * (compassBar.width / 360)) - (width * 0.5)) : 0 visible: _angle % 45 == 0 color: "#75505565" font.pointSize: ScreenTools.smallFontPointSize text: { switch(_angle) { case 0: return "N" case 45: return "NE" case 90: return "E" case 135: return "SE" case 180: return "S" case 225: return "SW" case 270: return "W" case 315: return "NW" } return "" } } } } Rectangle { id: headingIndicator height: ScreenTools.defaultFontPixelHeight width: ScreenTools.defaultFontPixelWidth * 4 color: qgcPal.windowShadeDark visible: !mainIsMap anchors.bottom: compassBar.top anchors.bottomMargin: ScreenTools.defaultFontPixelHeight * -0.1 anchors.horizontalCenter: parent.horizontalCenter QGCLabel { text: _heading color: qgcPal.text font.pointSize: ScreenTools.smallFontPointSize anchors.centerIn: parent } } Image { height: _indicatorsHeight width: height source: "/custom/img/compass_pointer.svg" visible: !mainIsMap fillMode: Image.PreserveAspectFit sourceSize.height: height anchors.top: compassBar.bottom anchors.topMargin: ScreenTools.defaultFontPixelHeight * -0.5 anchors.horizontalCenter: parent.horizontalCenter } //------------------------------------------------------------------------- //-- Vehicle Indicator Rectangle { id: vehicleIndicator color: qgcPal.window width: vehicleStatusGrid.width + (ScreenTools.defaultFontPixelWidth * 3) height: vehicleStatusGrid.height + (ScreenTools.defaultFontPixelHeight * 1.5) radius: 2 anchors.bottom: parent.bottom anchors.bottomMargin: ScreenTools.defaultFontPixelWidth anchors.right: attitudeIndicator.visible ? attitudeIndicator.left : parent.right anchors.rightMargin: attitudeIndicator.visible ? -ScreenTools.defaultFontPixelWidth : ScreenTools.defaultFontPixelWidth GridLayout { id: vehicleStatusGrid columnSpacing: ScreenTools.defaultFontPixelWidth * 1.5 rowSpacing: ScreenTools.defaultFontPixelHeight * 0.5 columns: 7 anchors.centerIn: parent //-- Compass Item { Layout.rowSpan: 3 Layout.column: 6 Layout.minimumWidth: mainIsMap ? parent.height * 1.25 : 0 Layout.fillHeight: true Layout.fillWidth: true //-- Large circle Rectangle { height: mainIsMap ? parent.height : 0 width: mainIsMap ? height : 0 radius: height * 0.5 border.color: qgcPal.text border.width: 1 color: Qt.rgba(0,0,0,0) anchors.centerIn: parent visible: mainIsMap } //-- North Label Rectangle { height: mainIsMap ? ScreenTools.defaultFontPixelHeight * 0.75 : 0 width: mainIsMap ? ScreenTools.defaultFontPixelWidth * 2 : 0 radius: ScreenTools.defaultFontPixelWidth * 0.25 color: qgcPal.windowShade visible: mainIsMap anchors.top: parent.top anchors.topMargin: ScreenTools.defaultFontPixelHeight * -0.25 anchors.horizontalCenter: parent.horizontalCenter QGCLabel { text: "N" color: qgcPal.text font.pointSize: ScreenTools.smallFontPointSize anchors.centerIn: parent } } //-- Needle Image { id: compassNeedle anchors.centerIn: parent height: mainIsMap ? parent.height * 0.75 : 0 width: height source: "/custom/img/compass_needle.svg" fillMode: Image.PreserveAspectFit visible: mainIsMap sourceSize.height: height transform: [ Rotation { origin.x: compassNeedle.width / 2 origin.y: compassNeedle.height / 2 angle: _heading }] } //-- Heading Rectangle { height: mainIsMap ? ScreenTools.defaultFontPixelHeight * 0.75 : 0 width: mainIsMap ? ScreenTools.defaultFontPixelWidth * 3.5 : 0 radius: ScreenTools.defaultFontPixelWidth * 0.25 color: qgcPal.windowShade visible: mainIsMap anchors.bottom: parent.bottom anchors.bottomMargin: ScreenTools.defaultFontPixelHeight * -0.25 anchors.horizontalCenter: parent.horizontalCenter QGCLabel { text: _heading color: qgcPal.text font.pointSize: ScreenTools.smallFontPointSize anchors.centerIn: parent } } } //-- Second Row //-- Chronometer QGCColoredImage { height: _indicatorsHeight width: height source: "/custom/img/chronometer.svg" fillMode: Image.PreserveAspectFit sourceSize.height: height Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter color: qgcPal.text } QGCLabel { id: firstLabel text: { if(activeVehicle) return secondsToHHMMSS(activeVehicle.getFact("flightTime").value) return "00:00:00" } color: _indicatorsColor font.pointSize: ScreenTools.smallFontPointSize Layout.fillWidth: true Layout.minimumWidth: indicatorValueWidth horizontalAlignment: Text.AlignLeft } //-- Ground Speed QGCColoredImage { height: _indicatorsHeight width: height source: "/custom/img/horizontal_speed.svg" fillMode: Image.PreserveAspectFit sourceSize.height: height Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter color: qgcPal.text } QGCLabel { text: activeVehicle ? activeVehicle.groundSpeed.value.toFixed(1) + ' ' + activeVehicle.groundSpeed.units : "0.0" color: _indicatorsColor font.pointSize: ScreenTools.smallFontPointSize Layout.fillWidth: true Layout.minimumWidth: indicatorValueWidth horizontalAlignment: firstLabel.horizontalAlignment } //-- Vertical Speed QGCColoredImage { height: _indicatorsHeight width: height source: "/custom/img/vertical_speed.svg" fillMode: Image.PreserveAspectFit sourceSize.height: height Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter color: qgcPal.text } QGCLabel { text: activeVehicle ? activeVehicle.climbRate.value.toFixed(1) + ' ' + activeVehicle.climbRate.units : "0.0" color: _indicatorsColor font.pointSize: ScreenTools.smallFontPointSize Layout.fillWidth: true Layout.minimumWidth: indicatorValueWidth horizontalAlignment: firstLabel.horizontalAlignment } //-- Third Row //-- Odometer QGCColoredImage { height: _indicatorsHeight width: height source: "/custom/img/odometer.svg" fillMode: Image.PreserveAspectFit sourceSize.height: height Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter color: qgcPal.text } QGCLabel { text: activeVehicle ? ('00000' + activeVehicle.flightDistance.value.toFixed(0)).slice(-5) + ' ' + activeVehicle.flightDistance.units : "00000" color: _indicatorsColor font.pointSize: ScreenTools.smallFontPointSize Layout.fillWidth: true Layout.minimumWidth: indicatorValueWidth horizontalAlignment: firstLabel.horizontalAlignment } //-- Altitude QGCColoredImage { height: _indicatorsHeight width: height source: "/custom/img/altitude.svg" fillMode: Image.PreserveAspectFit sourceSize.height: height Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter color: qgcPal.text } QGCLabel { text: _altitude color: _indicatorsColor font.pointSize: ScreenTools.smallFontPointSize Layout.fillWidth: true Layout.minimumWidth: indicatorValueWidth horizontalAlignment: firstLabel.horizontalAlignment } //-- Distance QGCColoredImage { height: _indicatorsHeight width: height source: "/custom/img/distance.svg" fillMode: Image.PreserveAspectFit sourceSize.height: height Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter color: qgcPal.text } QGCLabel { text: _distance ? _distanceStr : noGPS color: _distance ? _indicatorsColor : qgcPal.colorOrange font.pointSize: ScreenTools.smallFontPointSize Layout.fillWidth: true Layout.minimumWidth: indicatorValueWidth horizontalAlignment: firstLabel.horizontalAlignment } } } //------------------------------------------------------------------------- //-- Attitude Indicator Rectangle { color: qgcPal.window width: attitudeIndicator.width * 0.5 height: vehicleIndicator.height anchors.top: vehicleIndicator.top anchors.left: vehicleIndicator.right } Rectangle { id: attitudeIndicator anchors.bottom: vehicleIndicator.bottom anchors.bottomMargin: ScreenTools.defaultFontPixelWidth * -0.5 anchors.right: parent.right anchors.rightMargin: ScreenTools.defaultFontPixelWidth height: ScreenTools.defaultFontPixelHeight * 6 width: height radius: height * 0.5 color: qgcPal.windowShade CustomAttitudeWidget { size: parent.height * 0.95 vehicle: activeVehicle showHeading: false anchors.centerIn: parent } } }