Commit 4d4c024d authored by Gus Grubba's avatar Gus Grubba

Initial example of custom build

parent 903af1d7
message("Adding Custom Plugin")
#-- Version control
# Major and minor versions are defined here (manually)
CUSTOM_QGC_VER_MAJOR = 0
CUSTOM_QGC_VER_MINOR = 0
CUSTOM_QGC_VER_FIRST_BUILD = 0
# Build number is automatic
# Uses the current branch. This way it works on any branch including build-server's PR branches
CUSTOM_QGC_VER_BUILD = $$system(git --git-dir ../.git rev-list $$GIT_BRANCH --first-parent --count)
win32 {
CUSTOM_QGC_VER_BUILD = $$system("set /a $$CUSTOM_QGC_VER_BUILD - $$CUSTOM_QGC_VER_FIRST_BUILD")
} else {
CUSTOM_QGC_VER_BUILD = $$system("echo $(($$CUSTOM_QGC_VER_BUILD - $$CUSTOM_QGC_VER_FIRST_BUILD))")
}
CUSTOM_QGC_VERSION = $${CUSTOM_QGC_VER_MAJOR}.$${CUSTOM_QGC_VER_MINOR}.$${CUSTOM_QGC_VER_BUILD}
DEFINES -= GIT_VERSION=\"\\\"$$GIT_VERSION\\\"\"
DEFINES += GIT_VERSION=\"\\\"$$CUSTOM_QGC_VERSION\\\"\"
message(Custom QGC Version: $${CUSTOM_QGC_VERSION})
# Disable APM support
MAVLINK_CONF = common
CONFIG += QGC_DISABLE_APM_MAVLINK
CONFIG += QGC_DISABLE_APM_PLUGIN QGC_DISABLE_APM_PLUGIN_FACTORY QGC_DISABLE_PX4_PLUGIN_FACTORY
# MAVLink Development
exists($$PWD/mavlink_dev) {
MAVLINKPATH_REL = $$PWD/mavlink_dev
MAVLINKPATH = $$PWD/mavlink_dev
message($$sprintf("Using user-supplied mavlink development path '%1'", $$MAVLINKPATH))
}
# Branding
DEFINES += CUSTOMHEADER=\"\\\"CustomPlugin.h\\\"\"
DEFINES += CUSTOMCLASS=CustomPlugin
TARGET = CustomQGC
DEFINES += QGC_APPLICATION_NAME=\"\\\"CustomQGC\\\"\"
DEFINES += QGC_ORG_NAME=\"\\\"qgroundcontrol.org\\\"\"
DEFINES += QGC_ORG_DOMAIN=\"\\\"org.qgroundcontrol\\\"\"
RESOURCES += \
$$QGCROOT/custom/custom.qrc
QGC_APP_NAME = "Custom GS"
QGC_BINARY_NAME = "CustomQGC"
QGC_ORG_NAME = "Custom"
QGC_ORG_DOMAIN = "org.qgroundcontrol"
QGC_APP_DESCRIPTION = "Custom QGC Ground Station"
QGC_APP_COPYRIGHT = "Copyright (C) 2019 QGroundControl Development Team. All rights reserved."
QML_IMPORT_PATH += \
$$QGCROOT/custom/res
SOURCES += \
$$PWD/src/CustomPlugin.cc \
$$PWD/src/CustomQuickInterface.cc
HEADERS += \
$$PWD/src/CustomPlugin.h \
$$PWD/src/CustomQuickInterface.h
INCLUDEPATH += \
$$PWD/src \
#-------------------------------------------------------------------------------------
# Custom Firmware/AutoPilot Plugin
INCLUDEPATH += \
$$QGCROOT/custom/src/FirmwarePlugin \
$$QGCROOT/custom/src/AutoPilotPlugin
HEADERS+= \
$$QGCROOT/custom/src/AutoPilotPlugin/CustomAutoPilotPlugin.h \
$$QGCROOT/custom/src/FirmwarePlugin/CustomCameraControl.h \
$$QGCROOT/custom/src/FirmwarePlugin/CustomCameraManager.h \
$$QGCROOT/custom/src/FirmwarePlugin/CustomFirmwarePlugin.h \
$$QGCROOT/custom/src/FirmwarePlugin/CustomFirmwarePluginFactory.h \
SOURCES += \
$$QGCROOT/custom/src/AutoPilotPlugin/CustomAutoPilotPlugin.cc \
$$QGCROOT/custom/src/FirmwarePlugin/CustomCameraControl.cc \
$$QGCROOT/custom/src/FirmwarePlugin/CustomCameraManager.cc \
$$QGCROOT/custom/src/FirmwarePlugin/CustomFirmwarePlugin.cc \
$$QGCROOT/custom/src/FirmwarePlugin/CustomFirmwarePluginFactory.cc \
<RCC>
<qresource prefix="/custom">
<file alias="CustomArmedIndicator.qml">res/MainToolbar/CustomArmedIndicator.qml</file>
<file alias="CustomBatteryIndicator.qml">res/MainToolbar/CustomBatteryIndicator.qml</file>
<file alias="CustomCameraControl.qml">res/CustomCameraControl.qml</file>
<file alias="CustomFlyView.qml">res/CustomFlyView.qml</file>
<file alias="CustomGPSIndicator.qml">res/MainToolbar/CustomGPSIndicator.qml</file>
<file alias="CustomMainToolBar.qml">res/MainToolbar/CustomMainToolBar.qml</file>
<file alias="CustomMainToolBarIndicators.qml">res/MainToolbar/CustomMainToolBarIndicators.qml</file>
<file alias="CustomModeIndicator.qml">res/MainToolbar/CustomModeIndicator.qml</file>
<file alias="CustomMultiVehicleSelector.qml">res/MainToolbar/CustomMultiVehicleSelector.qml</file>
<file alias="CustomRCRSSIIndicator.qml">res/MainToolbar/CustomRCRSSIIndicator.qml</file>
</qresource>
<qresource prefix="custom/img">
<file alias="altitude.svg">res/Images/altitude.svg</file>
<file alias="attitude_crosshair.svg">res/Images/attitude_crosshair.svg</file>
<file alias="attitude_dial.svg">res/Images/attitude_dial.svg</file>
<file alias="attitude_pointer.svg">res/Images/attitude_pointer.svg</file>
<file alias="camera_photo.svg">res/Images/camera_photo.svg</file>
<file alias="camera_settings.svg">res/Images/camera_settings.svg</file>
<file alias="camera_video.svg">res/Images/camera_video.svg</file>
<file alias="chronometer.svg">res/Images/chronometer.svg</file>
<file alias="compass_needle.svg">res/Images/compass_needle.svg</file>
<file alias="compass_pointer.svg">res/Images/compass_pointer.svg</file>
<file alias="distance.svg">res/Images/distance.svg</file>
<file alias="horizontal_speed.svg">res/Images/horizontal_speed.svg</file>
<file alias="microSD.svg">res/Images/microSD.svg</file>
<file alias="odometer.svg">res/Images/odometer.svg</file>
<file alias="vertical_speed.svg">res/Images/vertical_speed.svg</file>
<file alias="void.png">res/Images/void.png</file>
</qresource>
<qresource prefix="Custom/Widgets">
<file alias="Custom/Widgets/CustomArtificialHorizon.qml">res/Custom/Widgets/CustomArtificialHorizon.qml</file>
<file alias="Custom/Widgets/CustomAttitudeWidget.qml">res/Custom/Widgets/CustomAttitudeWidget.qml</file>
<file alias="Custom/Widgets/CustomComboBox.qml">res/Custom/Widgets/CustomComboBox.qml</file>
<file alias="Custom/Widgets/CustomIconButton.qml">res/Custom/Widgets/CustomIconButton.qml</file>
<file alias="Custom/Widgets/CustomOnOffSwitch.qml">res/Custom/Widgets/CustomOnOffSwitch.qml</file>
<file alias="Custom/Widgets/CustomSignalStrength.qml">res/Custom/Widgets/CustomSignalStrength.qml</file>
<file alias="Custom/Widgets/CustomToolBarButton.qml">res/Custom/Widgets/CustomToolBarButton.qml</file>
<file alias="Custom/Widgets/CustomVehicleButton.qml">res/Custom/Widgets/CustomVehicleButton.qml</file>
<file alias="Custom/Widgets/qmldir">res/Custom/Widgets/qmldir</file>
</qresource>
</RCC>
/****************************************************************************
*
* (c) 2009-2019 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
* @file
* @author Gus Grubba <gus@auterion.com>
*/
import QtQuick 2.11
Item {
id: root
property real rollAngle : 0
property real pitchAngle: 0
property color skyColor1: Qt.hsla(0.6, 1.0, 0.25)
property color skyColor2: Qt.hsla(0.6, 0.5, 0.55)
property color groundColor1: Qt.hsla(0.25, 0.5, 0.45)
property color groundColor2: Qt.hsla(0.25, 0.75, 0.25)
clip: true
anchors.fill: parent
property real angularScale: pitchAngle * root.height / 45
Item {
id: artificialHorizon
width: root.width * 4
height: root.height * 8
anchors.centerIn: parent
Rectangle {
id: sky
anchors.fill: parent
smooth: true
antialiasing: true
gradient: Gradient {
GradientStop { position: 0.25; color: root.skyColor1 }
GradientStop { position: 0.5; color: root.skyColor2 }
}
}
Rectangle {
id: ground
height: sky.height / 2
anchors {
left: sky.left;
right: sky.right;
bottom: sky.bottom
}
smooth: true
antialiasing: true
gradient: Gradient {
GradientStop { position: 0.0; color: root.groundColor1 }
GradientStop { position: 0.25; color: root.groundColor2 }
}
}
transform: [
Translate {
y: angularScale
},
Rotation {
origin.x: artificialHorizon.width / 2
origin.y: artificialHorizon.height / 2
angle: -rollAngle
}]
}
}
/****************************************************************************
*
* (c) 2009-2019 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
* @file
* @author Gus Grubba <gus@auterion.com>
*/
import QtQuick 2.11
import QtGraphicalEffects 1.0
import QGroundControl 1.0
import QGroundControl.Controls 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.Palette 1.0
import QGroundControl.FlightMap 1.0
Item {
id: root
property bool showPitch: true
property var vehicle: null
property real size
property bool showHeading: false
property real _rollAngle: vehicle ? vehicle.roll.rawValue : 0
property real _pitchAngle: vehicle ? vehicle.pitch.rawValue : 0
width: size
height: size
Item {
id: instrument
anchors.fill: parent
visible: false
//----------------------------------------------------
//-- Artificial Horizon
CustomArtificialHorizon {
rollAngle: _rollAngle
pitchAngle: _pitchAngle
skyColor1: "#0a2e50"
skyColor2: "#2f85d4"
groundColor1: "#897459"
groundColor2: "#4b3820"
anchors.fill: parent
}
//----------------------------------------------------
//-- Instrument Dial
Image {
id: instrumentDial
source: "/custom/img/attitude_dial.svg"
mipmap: true
fillMode: Image.PreserveAspectFit
anchors.fill: parent
sourceSize.height: parent.height
transform: Rotation {
origin.x: root.width / 2
origin.y: root.height / 2
angle: -_rollAngle
}
}
//----------------------------------------------------
//-- Pointer
Image {
id: pointer
height: size * 0.0625
width: height
source: "/custom/img/attitude_pointer.svg"
antialiasing: true
fillMode: Image.PreserveAspectFit
sourceSize.height: height
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
}
//----------------------------------------------------
//-- Pitch
QGCPitchIndicator {
id: pitchWidget
visible: root.showPitch
size: root.size * 0.5
anchors.verticalCenter: parent.verticalCenter
pitchAngle: _pitchAngle
rollAngle: _rollAngle
color: Qt.rgba(0,0,0,0)
}
//----------------------------------------------------
//-- Cross Hair
Image {
id: crossHair
anchors.centerIn: parent
source: "/custom/img/attitude_crosshair.svg"
mipmap: true
width: size * 0.75
sourceSize.width: width
fillMode: Image.PreserveAspectFit
}
}
Rectangle {
id: mask
anchors.fill: instrument
radius: width / 2
color: "black"
visible: false
}
OpacityMask {
anchors.fill: instrument
source: instrument
maskSource: mask
}
Rectangle {
id: borderRect
anchors.fill: parent
radius: width / 2
color: Qt.rgba(0,0,0,0)
border.color: "#000"
border.width: 1
}
QGCLabel {
anchors.bottomMargin: Math.round(ScreenTools.defaultFontPixelHeight * 0.5)
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
text: _headingString3
color: "white"
visible: showHeading
font.pointSize: ScreenTools.smallFontPointSize
property string _headingString: vehicle ? vehicle.heading.rawValue.toFixed(0) : "OFF"
property string _headingString2: _headingString.length === 1 ? "0" + _headingString : _headingString
property string _headingString3: _headingString2.length === 2 ? "0" + _headingString2 : _headingString2
}
}
/****************************************************************************
*
* (c) 2009-2019 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
* @file
* @author Gus Grubba <gus@auterion.com>
*/
import QtQuick 2.11
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QGroundControl.Controls 1.0
import QGroundControl.Palette 1.0
import QGroundControl.ScreenTools 1.0
Button {
id: combo
property real pointSize: ScreenTools.defaultFontPointSize ///< Point size for button text
property bool centeredLabel: false
property alias model: popupItems.model
property alias textRole: popup.textRole
property alias currentIndex: popup.__selectedIndex
readonly property alias count: popupItems.count
readonly property alias currentText: popup.currentText
property var _qgcPal: QGCPalette { colorGroupEnabled: enabled }
property int _verticalPadding: Math.round(ScreenTools.defaultFontPixelHeight * 0.5)
property real _dropImageWidth: ScreenTools.defaultFontPixelHeight * 0.5
property real _dropImageMargin: _dropImageWidth * 0.5
property var __popup: popup
signal activated(int index)
style: ButtonStyle {
/*! This defines the background of the button. */
background: Rectangle {
implicitWidth: Math.round(ScreenTools.defaultFontPixelWidth * 6)
implicitHeight: Math.round(ScreenTools.defaultFontPixelHeight)
color: Qt.rgba(0,0,0,0)
/*
Image {
id: image
width: _dropImageWidth
height: _dropImageWidth
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: _dropImageMargin
anchors.right: parent.right
source: "/custom/img/menu_dropdown.svg"
}
*/
}
/*! This defines the label of the button. */
label: Item {
implicitWidth: text.implicitWidth
implicitHeight: text.implicitHeight
baselineOffset: text.y + text.baselineOffset
QGCLabel {
id: text
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: centeredLabel ? parent.horizontalCenter : undefined
text: control.currentText
color: "#FFF"
font.pointSize: combo.pointSize
}
}
}
onClicked: {
combo.focus = true
popup.toggleShow()
}
Component.onCompleted: {
if (currentIndex === -1) {
currentIndex = 0
}
popup.resolveTextValue(textRole)
}
function textAt (index) {
if (index >= count || index < 0)
return null;
return popupItems.objectAt(index).text;
}
function find (text) {
for (var i = 0 ; i < popupItems.count ; ++i) {
var currentString = popupItems.objectAt(i).text
if (text === currentString) {
return i
}
}
return -1
}
ExclusiveGroup { id: eg }
Menu {
id: popup
__minimumWidth: combo.width
__visualItem: combo
style: MenuStyle {
font.pointSize: combo.pointSize
font.family: ScreenTools.normalFontFamily
__labelColor: combo._qgcPal.buttonText
__selectedLabelColor: combo._qgcPal.buttonHighlightText
__selectedBackgroundColor: combo._qgcPal.buttonHighlight
__backgroundColor: combo._qgcPal.button
__maxPopupHeight: 600
__menuItemType: "comboboxitem"
__scrollerStyle: ScrollViewStyle { }
}
property string textRole: ""
property bool showing: false
property string currentText: selectedText
property string selectedText
onSelectedTextChanged: popup.currentText = selectedText
on__SelectedIndexChanged: {
if (__selectedIndex === -1)
popup.currentText = ""
else
updateSelectedText()
}
property int _y: combo.height
property bool _modelIsArray: false
onAboutToShow: showing = true
onAboutToHide: showing = false
function toggleShow() {
if (popup._popupVisible) {
popup.__dismissAndDestroy()
} else {
__popup(Qt.rect(0, _y, 0, 0), 0)
}
}
function resolveTextValue(initialTextRole) {
if (!model) {
return
}
var get = model['get'];
if (!get && popup._modelIsArray && !!model[0]) {
if (model[0].constructor !== String && model[0].constructor !== Number)
get = function(i) { return model[i]; }
}
var modelMayHaveRoles = get !== undefined
textRole = initialTextRole
if (textRole === "" && modelMayHaveRoles && get(0)) {
// No text role set, check whether model has a suitable role
// If 'text' is found, or there's only one role, pick that.
var listElement = get(0)
var roleName = ""
var roleCount = 0
for (var role in listElement) {
if (listElement[role].constructor === Function)
continue;
if (role === "text") {
roleName = role
break
} else if (!roleName) {
roleName = role
}
++roleCount
}
if (roleCount > 1 && roleName !== "text") {
console.warn("No suitable 'textRole' found for ComboBox.")
} else {
textRole = roleName
}
}
updateSelectedText()
}
function updateSelectedText() {
var selectedItem
if (__selectedIndex !== -1 && (selectedItem = items[__selectedIndex])) {
selectedText = Qt.binding(function () { return selectedItem.text })
if (currentText !== selectedText) // __selectedIndex went form -1 to 0
selectedTextChanged()
}
}
Instantiator {
id: popupItems
onModelChanged: {
popup._modelIsArray = !!model ? model.constructor === Array : false
popup.resolveTextValue(popup.textRole)
}
onObjectAdded: {
// There is a bug in Instantiator which can cause objects to be added out of order from an index standpoint.
// If not handled correctly this will cause menu items to be added incorrectly due to the way Menu.insertItem works.
//console.log("menu add", index, object.text)
if (index === popup.__selectedIndex) {
popup.selectedText = object["text"]
}
// Find the correct place for menu item. We can't just add at index, due to possible bad ordering
var insertIndex = -1
for (var i=0; i<popup.items.length; i++) {
//console.log("position search", i, popup.items[i].itemIndex)
if (popup.items[i].itemIndex > index) {
insertIndex = i
break
}
}
if (insertIndex === -1) {
popup.insertItem(popup.items.length, object)
} else {
//console.log("out of order menu add", index, insertIndex)
popup.insertItem(insertIndex, object)
}
}
onObjectRemoved: popup.removeItem(object)
MenuItem {
text: popup.textRole === '' ? modelData : ((popup._modelIsArray ? modelData[popup.textRole] : model[popup.textRole]) || '')
checked: index == currentIndex
checkable: true
exclusiveGroup: eg
property int itemIndex: index
onTriggered: {
//console.log("onTriggered", index, currentIndex)
if (index !== currentIndex) {
//console.log("activated", index)
activated(index)
}
}
}
}
}
}
/****************************************************************************
*
* (c) 2009-2019 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
* @file
* @author Gus Grubba <gus@auterion.com>
*/
import QtQuick 2.11
import QtQuick.Controls 2.4
import QGroundControl 1.0
import QGroundControl.Controls 1.0
import QGroundControl.Palette 1.0
import QGroundControl.ScreenTools 1.0
import QtGraphicalEffects 1.0
Button {
id: _rootButton
width: parent.height * 1.25
height: parent.height
flat: true
contentItem: Item {
id: _content
anchors.fill: _rootButton
Row {
id: _edge
spacing: ScreenTools.defaultFontPixelWidth * 0.25
anchors.left: parent.left
anchors.leftMargin: ScreenTools.defaultFontPixelWidth
anchors.verticalCenter: parent.verticalCenter
Repeater {
model: [1,2,3]
Rectangle {
height: ScreenTools.defaultFontPixelHeight
width: ScreenTools.defaultFontPixelWidth * 0.25
color: qgcPal.text
opacity: 0.75
}
}
}
Image {
id: _icon
height: _rootButton.height * 0.75
width: height
smooth: true
mipmap: true
antialiasing: true
fillMode: Image.PreserveAspectFit
source: "/res/QGCLogoWhite"
sourceSize.height: height
anchors.left: _edge.right
anchors.leftMargin: ScreenTools.defaultFontPixelWidth
anchors.verticalCenter: parent.verticalCenter
}
}
background: Item {
anchors.fill: parent
}
}
/****************************************************************************
*
* (c) 2009-2019 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
* @file
* @author Gus Grubba <gus@auterion.com>
*/
import QtQuick 2.3
import QGroundControl.Palette 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.Controls 1.0
Rectangle {
id: _root
height: Math.round(ScreenTools.defaultFontPixelHeight * 2)
width: ScreenTools.defaultFontPixelWidth * 10
color: qgcPal.button
border.color: qgcPal.text
border.width: 1
property bool checked: true
signal clicked
QGCPalette { id: qgcPal; colorGroupEnabled: true }
Rectangle {
width: parent.width * 0.5
height: parent.height
color: qgcPal.windowShade
visible: !checked
border.color: qgcPal.text
border.width: 1
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
QGCLabel {
text: qsTr("Off")
anchors.centerIn: parent
}
}
Rectangle {
width: parent.width * 0.5
height: parent.height * 0.95
color: qgcPal.buttonHighlight
visible: checked
border.color: qgcPal.text
border.width: 1
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
QGCLabel {
text: qsTr("On")
color: qgcPal.buttonHighlightText
anchors.centerIn: parent
}
}
MouseArea {
anchors.fill: parent
onClicked: {
checked = !checked
_root.clicked()
}
}
}
/****************************************************************************
*
* (c) 2009-2019 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
* @file
* @author Gus Grubba <gus@auterion.com>
*/
import QtQuick 2.11
import QtQuick.Controls 1.4
import QGroundControl 1.0
import QGroundControl.Controls 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.Palette 1.0
Item {
width: size
height: size
property real size: 50
property real percent: 0
QGCPalette { id: qgcPal }
function getIcon() {
if (percent < 20)
return "/custom/img/menu_signal_0.svg"
if (percent < 40)
return "/custom/img/menu_signal_25.svg"
if (percent < 60)
return "/custom/img/menu_signal_50.svg"
if (percent < 90)
return "/custom/img/menu_signal_75.svg"
return "/custom/img/menu_signal_100.svg"
}
QGCColoredImage {
source: getIcon()
fillMode: Image.PreserveAspectFit
anchors.fill: parent
sourceSize.height: size
color: qgcPal.text
}
}
/****************************************************************************
*
* (c) 2009-2019 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
* @file
* @author Gus Grubba <gus@auterion.com>
*/
import QtQuick 2.11
import QtQuick.Controls 2.4
import QGroundControl.Controls 1.0
import QGroundControl.Palette 1.0
import QGroundControl.ScreenTools 1.0
Button {
id: button
autoExclusive: true
background: Rectangle {
anchors.fill: parent
color: mouseArea.pressed ? qgcPal.buttonHighlight : Qt.rgba(0,0,0,0)
}
contentItem: Row {
spacing: ScreenTools.defaultFontPixelWidth
anchors.left: button.left
anchors.leftMargin: ScreenTools.defaultFontPixelWidth
anchors.verticalCenter: button.verticalCenter
Item {
height: ScreenTools.defaultFontPixelHeight * 3
width: 1
}
QGCColoredImage {
id: _icon
height: ScreenTools.defaultFontPixelHeight
width: height
sourceSize.height: parent.height
fillMode: Image.PreserveAspectFit
color: (mouseArea.pressed || button.checked) ? qgcPal.buttonHighlightText : qgcPal.buttonText
source: button.icon.source
anchors.verticalCenter: parent.verticalCenter
}
Label {
id: _label
visible: text !== ""
text: button.text
color: (mouseArea.pressed || button.checked) ? qgcPal.buttonHighlightText : qgcPal.buttonText
anchors.verticalCenter: parent.verticalCenter
}
}
// Process hover events
MouseArea {
id: mouseArea
anchors.fill: parent
onClicked: button.clicked()
}
}
/****************************************************************************
*
* (c) 2009-2019 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
* @file
* @author Gus Grubba <gus@auterion.com>
*/
import QtQuick 2.11
import QtQuick.Controls 2.4
import QGroundControl.Controls 1.0
import QGroundControl.Palette 1.0
import QGroundControl.ScreenTools 1.0
Button {
id: button
height: _infoCol.height * 1.25
autoExclusive: true
property var vehicle: null
function getBatteryColor() {
if(vehicle) {
if(vehicle.battery.percentRemaining.value > 75) {
return qgcPal.colorGreen
}
if(vehicle.battery.percentRemaining.value > 50) {
return qgcPal.colorOrange
}
if(vehicle.battery.percentRemaining.value > 0.1) {
return qgcPal.colorRed
}
}
return qgcPal.colorGrey
}
function getBatteryPercentage() {
if(vehicle) {
return vehicle.battery.percentRemaining.value / 100.0
}
return 1
}
background: Rectangle {
anchors.fill: parent
color: button.checked ? qgcPal.buttonHighlight : qgcPal.button
radius: ScreenTools.defaultFontPixelWidth * 0.5
}
contentItem: Row {
spacing: ScreenTools.defaultFontPixelWidth
anchors.margins: ScreenTools.defaultFontPixelWidth
anchors.verticalCenter: button.verticalCenter
QGCColoredImage {
id: _icon
height: ScreenTools.defaultFontPixelHeight * 1.5
width: height
sourceSize.height: parent.height
fillMode: Image.PreserveAspectFit
color: qgcPal.buttonText
source: "/qmlimages/PaperPlane.svg"
anchors.verticalCenter: parent.verticalCenter
}
Column {
id: _infoCol
spacing: ScreenTools.defaultFontPixelHeight * 0.25
QGCLabel {
text: qsTr("Vehicle ") + (vehicle ? vehicle.id : qsTr("None"))
font.family: ScreenTools.demiboldFontFamily
color: qgcPal.buttonText
}
Row {
spacing: ScreenTools.defaultFontPixelWidth
QGCLabel {
text: vehicle ? vehicle.flightMode : qsTr("None")
color: qgcPal.buttonText
}
Rectangle {
height: ScreenTools.defaultFontPixelHeight * 0.5
width: ScreenTools.defaultFontPixelWidth * 3
color: Qt.rgba(0,0,0,0)
anchors.verticalCenter: parent.verticalCenter
Rectangle {
height: parent.height
width: parent.width * getBatteryPercentage()
color: getBatteryColor()
anchors.right: parent.right
}
}
}
}
}
}
Module Custom.Widgets
CustomArtificialHorizon 1.0 CustomArtificialHorizon.qml
CustomAttitudeWidget 1.0 CustomAttitudeWidget.qml
CustomComboBox 1.0 CustomComboBox.qml
CustomIconButton 1.0 CustomIconButton.qml
CustomOnOffSwitch 1.0 CustomOnOffSwitch.qml
CustomSignalStrength 1.0 CustomSignalStrength.qml
CustomToolBarButton 1.0 CustomToolBarButton.qml
CustomVehicleButton 1.0 CustomVehicleButton.qml
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
<svg width="72" height="72" viewBox="0 0 72 72" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M58 63H46.9V39.8H25.1V63H14V9H25.1V30.9H46.8V9H57.9L58 63Z" fill="white"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 288 36" style="enable-background:new 0 0 288 36;" xml:space="preserve">
<style type="text/css">
.st0{fill:none;}
.st1{fill:none;stroke:#0A94FF;stroke-width:4;stroke-miterlimit:10;}
.st2{fill:none;stroke:#0A94FF;stroke-width:4;stroke-linecap:round;stroke-miterlimit:10;}
</style>
<rect class="st0" width="288" height="36"/>
<line class="st1" x1="0" y1="18" x2="72" y2="18"/>
<line class="st1" x1="288" y1="18" x2="216" y2="18"/>
<polyline class="st2" points="194.5,31.1 144,18 93.5,31.1 "/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 288 288" style="enable-background:new 0 0 288 288;" xml:space="preserve">
<style type="text/css">
.st0{fill:none;stroke:#FFFFFF;stroke-width:4;}
.st1{fill:none;}
</style>
<g>
<line class="st0" x1="144" y1="45.8" x2="144" y2="18.8"/>
<line class="st0" x1="171.7" y1="40.5" x2="176.4" y2="23.1"/>
<line class="st0" x1="197.6" y1="51.2" x2="206.6" y2="35.6"/>
<line class="st0" x1="219.8" y1="68.2" x2="232.5" y2="55.5"/>
<line class="st0" x1="236.8" y1="90.4" x2="252.4" y2="81.4"/>
<line class="st0" x1="116.3" y1="40.4" x2="111.6" y2="23"/>
<line class="st0" x1="90.4" y1="51.1" x2="81.4" y2="35.5"/>
<line class="st0" x1="68.2" y1="68.2" x2="55.5" y2="55.4"/>
<line class="st0" x1="51.1" y1="90.3" x2="35.6" y2="81.3"/>
<rect x="135" y="270" class="st1" width="18" height="18"/>
<g id="Layer_3">
</g>
</g>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_3" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 288 288" style="enable-background:new 0 0 288 288;" xml:space="preserve">
<style type="text/css">
.st0{fill-rule:evenodd;clip-rule:evenodd;fill:#231F20;}
</style>
<path id="pointer_2_" class="st0" d="M276.5,0L144,288L11.5,0"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1"
id="Layer_1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 288 288"
style="enable-background:new 0 0 288 288;" xml:space="preserve">
<g transform="translate(0,-952.36218)">
<path d="M102.3,978.9c-3.2,0.1-5.5,2.1-6.7,4.1l-13.1,26.2H30.3c-16.7,0-30.3,13.7-30.3,30.3v144c0,16.7,13.7,30.3,30.3,30.3h227.4
c16.7,0,30.3-13.7,30.3-30.3v-144c0-16.7-13.7-30.3-30.3-30.3h-52.1L192.4,983c-1.3-2.5-4-4.1-6.7-4.1H102.3z M106.9,994h74.1
l13,26.1c1.2,2.5,3.9,4.2,6.7,4.3h56.8c8.5,0,15.2,6.6,15.2,15.2v144c0,8.5-6.6,15.2-15.2,15.2H30.3c-8.5,0-15.2-6.6-15.2-15.2
v-144c0-8.5,6.6-15.2,15.2-15.2h56.8c2.8,0,5.5-1.7,6.7-4.3L106.9,994z M144,1047.1c-35.5,0-64.4,28.9-64.4,64.4
c0,35.5,28.9,64.4,64.4,64.4c35.5,0,64.4-28.9,64.4-64.4C208.4,1076,179.5,1047.1,144,1047.1z M144,1062.3
c27.3,0,49.3,22,49.3,49.3c0,27.3-22,49.3-49.3,49.3c-27.3,0-49.3-22-49.3-49.3C94.7,1084.2,116.7,1062.3,144,1062.3z"/>
</g>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 72 72" style="enable-background:new 0 0 72 72;" xml:space="preserve">
<style type="text/css">
.st0{fill-rule:evenodd;clip-rule:evenodd;}
</style>
<path class="st0" d="M63.6,65.5h-5.5V40h5.5V65.5z M18.6,31.2H3.4c-4.5,0-4.5-9.1,0-9.1h15.2C23.2,22.1,23.2,31.2,18.6,31.2z
M8.2,65.5h5.7V35H8.2V65.5z M8.2,18.3V6.5h5.7v11.8H8.2z M28.4,51h15.2c4.5,0,4.5-9.3,0-9.3H28.4C23.9,41.7,23.9,51,28.4,51z
M38.6,65.5h-5.5V54.6h5.5V65.5z M33.2,6.5V38h5.5V6.4L33.2,6.5L33.2,6.5z M68.4,36.2h-15c-4.8,0-4.8-9.1,0-9.1h15
C73.2,27.1,73.2,36.2,68.4,36.2z M58.2,6.5v16.8h5.4V6.5H58.2z"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 288 288" style="enable-background:new 0 0 288 288;" xml:space="preserve">
<g>
<path d="M21.2,215.3h168.7c11.7,0,21.2-9.5,21.2-21.2V93.9c0-11.7-9.5-21.2-21.2-21.2H21.2C9.5,72.7,0,82.2,0,93.9v100.2
C0,205.8,9.5,215.3,21.2,215.3z"/>
<polygon points="225.2,165.5 288,206.1 288,81.9 225.2,122.5 "/>
</g>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 72 72" style="enable-background:new 0 0 72 72;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<path class="st0" d="M36,5.3c4.2,0,8.2,0.8,12,2.4c3.7,1.5,6.9,3.8,9.8,6.6c2.8,2.8,5,6.1,6.6,9.8c1.6,3.8,2.4,7.8,2.4,12
c0,4.1-0.8,8.2-2.4,12c-1.5,3.7-3.8,6.9-6.6,9.8c-2.8,2.8-6.1,5-9.8,6.6c-3.8,1.6-7.8,2.4-12,2.4c-4.2,0-8.2-0.8-12-2.4
c-3.7-1.5-6.9-3.8-9.8-6.6c-2.8-2.8-5-6.1-6.6-9.8c-1.6-3.8-2.4-7.8-2.4-12c0-4.1,0.8-8.2,2.4-12c1.5-3.7,3.8-6.9,6.6-9.8
c2.8-2.8,6.1-5,9.8-6.6C27.8,6.1,31.9,5.3,36,5.3z M36,0C16.1,0,0,16.1,0,36s16.1,36,36,36s36-16.1,36-36S55.9,0,36,0z"/>
<path class="st0" d="M45.2,47.9c-0.7,0-1.4-0.3-1.9-0.8l-10-10V13.5c0-1.5,1.2-2.6,2.6-2.6c1.5,0,2.6,1.2,2.6,2.6v21.3l8.4,8.4
c1,1,1,2.7,0,3.7C46.6,47.6,45.9,47.9,45.2,47.9L45.2,47.9z"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 288 288" style="enable-background:new 0 0 288 288;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
.st1{fill:#236A00;}
.st2{fill:#00B423;}
</style>
<g>
<path class="st0" d="M205.2,206.7L144,173.4V81.3"/>
<path class="st0" d="M144,81.3v92.2l-61.2,33.3"/>
</g>
<path class="st1" d="M198,199.3L144,170V88.7"/>
<path class="st2" d="M144,88.7V170l-54,29.4"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 72 72" style="enable-background:new 0 0 72 72;" xml:space="preserve">
<style type="text/css">
.st0{fill-rule:evenodd;clip-rule:evenodd;fill:#0B1629;}
</style>
<path class="st0" d="M5.3,58c-5.6,0-7-3.6-3-8.2l30.1-34.1c2-2.3,5.3-2.2,7.3,0l30.1,34.1c4,4.5,2.6,8.2-3,8.2H5.3z"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 72 72" style="enable-background:new 0 0 72 72;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
.st1{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
</style>
<path class="st0" d="M7.7,9v53.9V63h17.2c4.9,0,9.2-1.1,13.1-3.3c3.9-2.1,7-5.2,9-9.1c0.8-1.4,1.5-3,2-4.6H37.2
c-0.6,1.4-1.3,2.6-2.2,3.7c-2.4,2.9-5.9,4.3-10.4,4.3h-5.5V18h5.6c4.6,0,8,1.5,10.4,4.3c1.3,1.6,2.3,3.6,2.9,6.1h11.6
c-0.5-2.5-1.4-4.9-2.7-7.1c-2.1-3.9-5.1-7-9-9.1C34.2,10,29.8,9,24.9,9H7.7z"/>
<path class="st1" d="M47.8,35l-5.7,1.2c-1.2,0.3-1.2,2,0,2.3l5.7,1.2l4.7,2.1l0,3.5l6.4-4l4.8-3c0.7-0.4,0.7-1.5,0-1.9l-4.9-3
l-6.4-4l0,3.5L47.8,35z"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 72 72" style="enable-background:new 0 0 72 72;" xml:space="preserve">
<style type="text/css">
.st0{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
.st1{fill:#FFFFFF;}
</style>
<path class="st0" d="M18.6,31.7l-7.3,1.9c-2.7,0.7-2.6,4.5,0,5.1l7.4,1.8l16,3.9l0,6.6l10.2-7.5l7.9-5.9c1.1-0.8,1.1-2.5,0-3.3
l-7.9-5.8L34.6,21l0,6.6L18.6,31.7z"/>
<rect x="64.5" y="14" class="st1" width="5.5" height="44.3"/>
</svg>
<svg width="16" height="13" viewBox="0 0 16 13" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.9992 1.15794C15.9992 0.795041 15.718 0.500817 15.3711 0.500817L0.628867 0.5C0.281225 0.5 0 0.794224 0 1.15793V10.0903C0 10.4532 0.281225 10.7474 0.628867 10.7474H5.14583C5.27473 10.7474 5.39816 10.8006 5.48957 10.8946L6.41842 11.8525C6.52311 11.9603 6.66295 12.02 6.8098 12.02H8.37926V11.5607C8.37926 11.4806 8.44176 11.4144 8.5191 11.4144H9.74715C9.7784 11.4144 9.80809 11.4258 9.83387 11.4454L10.4917 11.9881C10.5167 12.0094 10.5471 12.0192 10.5784 12.0192H15.3719C15.7188 12.0192 16 11.7258 16 11.3621L15.9992 1.15794ZM4.32879 9.68253C4.32879 9.75118 4.27489 9.80758 4.20927 9.80758H1.31722C1.25082 9.80758 1.19769 9.75118 1.19769 9.68253V9.0352C1.19769 8.96655 1.2516 8.91015 1.31722 8.91015H4.21007C4.27569 8.91015 4.32959 8.96655 4.32959 9.0352L4.32879 9.68253ZM4.20927 8.70339C4.27489 8.70339 4.32879 8.64618 4.32879 8.57752L4.32959 7.92938C4.32959 7.85991 4.27569 7.80351 4.21007 7.80351H1.31722C1.2516 7.80351 1.19769 7.85991 1.19769 7.92938V8.57671C1.19769 8.64618 1.25082 8.70257 1.31722 8.70257L4.20927 8.70339ZM4.32879 7.47087C4.32879 7.53952 4.27489 7.59592 4.20927 7.59592H1.31722C1.25082 7.59592 1.19769 7.53952 1.19769 7.47087V6.82354C1.19769 6.75489 1.2516 6.69767 1.31722 6.69767H4.21007C4.27569 6.69767 4.32959 6.75407 4.32959 6.82354L4.32879 7.47087ZM4.20927 6.49089C4.27489 6.49089 4.32879 6.4345 4.32879 6.36503V5.7177C4.32879 5.64904 4.27489 5.59265 4.20927 5.59265H0.957038C0.891415 5.59265 0.837512 5.64823 0.837512 5.7177V6.36503C0.837512 6.4345 0.891417 6.49089 0.957038 6.49089H4.20927ZM4.32879 5.25837C4.32879 5.32784 4.27489 5.38342 4.20927 5.38342L1.31722 5.38424C1.25082 5.38424 1.19769 5.32784 1.19769 5.25919V4.61186C1.19769 4.54239 1.2516 4.48681 1.31722 4.48681H4.21007C4.27569 4.48681 4.32959 4.5432 4.32959 4.61186L4.32879 5.25837ZM4.20927 4.27758C4.27489 4.27758 4.32879 4.22118 4.32879 4.15253V3.5052C4.32879 3.43655 4.27489 3.38015 4.20927 3.38015H0.957038C0.891415 3.38015 0.837512 3.43573 0.837512 3.5052V4.15253C0.837512 4.22118 0.891417 4.27758 0.957038 4.27758H4.20927ZM4.32879 3.04587C4.32879 3.11534 4.27489 3.17092 4.20927 3.17092L1.31722 3.17174C1.25082 3.17174 1.19769 3.11534 1.19769 3.04669V2.39936C1.19769 2.33071 1.2516 2.27431 1.31722 2.27431H4.21007C4.27569 2.27431 4.32959 2.33071 4.32959 2.39936L4.32879 3.04587ZM4.20927 2.06508C4.27489 2.06508 4.32879 2.00868 4.32879 1.94003L4.32959 1.2927C4.32959 1.22323 4.27569 1.16684 4.21007 1.16684H1.31722C1.2516 1.16684 1.19769 1.22323 1.19769 1.2927V1.94003C1.19769 2.00869 1.25082 2.06508 1.31722 2.06508H4.20927Z" fill="white"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 72 72" style="enable-background:new 0 0 72 72;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
.st1{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
.st2{font-family:'Menlo-Regular';}
.st3{font-size:46px;}
</style>
<path class="st0" d="M47,15.9c-0.6,0-1.2,0.3-1.6,0.7c-0.4,0.4-0.7,1-0.6,1.6c0,4.6,1.3,8.8,4.1,11.5c1.4,1.4,3.1,2.2,5,2.2
c1.8,0,3.6-0.8,5-2.1c2.8-2.7,4.1-6.9,4.1-11.5l0,0c0-1.3-1-2.3-2.3-2.3s-2.3,1-2.3,2.3c0,3.6-1.3,6.8-2.7,8.2
c-0.7,0.7-1.3,0.9-1.8,0.9s-1.1-0.2-1.8-0.9c-1.4-1.4-2.7-4.7-2.7-8.3l0,0c0-0.6-0.2-1.2-0.7-1.7C48.2,16.1,47.6,15.9,47,15.9
L47,15.9z"/>
<path class="st0" d="M2,14.8c-1.2,0.1-2.1,1.1-2,2.3v37.8c0,1.3,1,2.3,2.3,2.3h67.4c1.3,0,2.3-1,2.3-2.3V17.1c0-1.3-1-2.3-2.3-2.3H2
z M2.1,16.9l67.6,0.2v37.8H2.3L2.1,16.9z"/>
<path class="st0" d="M53.9,36.3c-2.3,0-4.5,1.3-6.1,3.3c-3.1,4.1-3.9,10.2-2.4,15.7l0,0c0.3,1.2,1.6,1.9,2.8,1.6
c1.2-0.3,1.9-1.6,1.6-2.8c-1.1-4.1-0.2-9.3,1.6-11.7c0.9-1.2,1.8-1.6,2.4-1.5c0.7,0,1.5,0.3,2.4,1.6c1.8,2.5,2.7,7.7,1.5,11.7l0,0
c-0.2,0.6-0.2,1.3,0.1,1.8c0.3,0.6,0.8,1,1.4,1.2c0.6,0.2,1.3,0.1,1.8-0.3c0.5-0.3,0.9-0.9,1-1.5c1.5-5.4,0.8-11.6-2.3-15.7
C58.3,37.6,56.2,36.3,53.9,36.3L53.9,36.3z"/>
<path class="st1" d="M35.6,16.6v38.3h4.6V16.6H35.6z"/>
<text transform="matrix(1 0 0 1 5.3209 52.9379)" class="st0 st2 st3">1</text>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 72 72" style="enable-background:new 0 0 72 72;" xml:space="preserve">
<style type="text/css">
.st0{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
.st1{fill:#FFFFFF;}
</style>
<path class="st0" d="M31.7,53.4l3.4,13.3c0.3,1.1,1.9,1.1,2.1,0l3.2-13.4l3.9-16l6.6,0l-7.5-10.2l-5.1-6.9c-1.2-1.6-3.6-1.6-4.8,0
l-5.1,6.9L21,37.4l6.6,0L31.7,53.4z"/>
<rect x="13.9" y="2.2" class="st1" width="44.3" height="5.5"/>
</svg>
/****************************************************************************
*
* (c) 2009-2019 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
* @file
* @author Gus Grubba <gus@auterion.com>
*/
import QtQuick 2.11
import QtQuick.Controls 1.2
import QGroundControl 1.0
import QGroundControl.MultiVehicleManager 1.0
import QGroundControl.Controls 1.0
import QGroundControl.Palette 1.0
import QGroundControl.ScreenTools 1.0
//-------------------------------------------------------------------------
//-- Armed Indicator
Rectangle {
anchors.top: parent.top
anchors.bottom: parent.bottom
width: labelRow.width + (ScreenTools.defaultFontPixelWidth * 6)
color: qgcPal.windowShade
property bool _armed: activeVehicle ? activeVehicle.armed : false
Row {
id: labelRow
spacing: ScreenTools.defaultFontPixelWidth
anchors.centerIn: parent
QGCLabel {
id: labelText
text: _armed ? qsTr("Armed") : qsTr("Disarmed")
color: qgcPal.text
font.pointSize: ScreenTools.defaultFontPointSize
anchors.verticalCenter: parent.verticalCenter
}
Rectangle {
height: ScreenTools.defaultFontPixelHeight * 0.5
width: height
radius: height * 0.5
color: _armed ? qgcPal.colorGreen : qgcPal.colorRed
border.color: qgcPal.window
border.width: 1
anchors.verticalCenter: parent.verticalCenter
}
}
QGCMouseArea {
fillItem: parent
onClicked: _armed ? mainWindow.disarmVehicle() : mainWindow.armVehicle()
}
}
/****************************************************************************
*
* (c) 2009-2019 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
* @file
* @author Gus Grubba <gus@auterion.com>
*/
import QtQuick 2.11
import QtQuick.Controls 1.4
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
//-------------------------------------------------------------------------
//-- Battery Indicator
Item {
id: _root
width: batteryIndicatorRow.width
anchors.top: parent.top
anchors.bottom: parent.bottom
property var battery1: activeVehicle ? activeVehicle.battery : null
property var battery2: activeVehicle ? activeVehicle.battery2 : null
property bool hasSecondBattery: battery2 && battery2.voltage.value !== -1
function lowestBattery() {
if(activeVehicle) {
if(hasSecondBattery) {
if(activeVehicle.battery2.percentRemaining.value < activeVehicle.battery.percentRemaining.value) {
return activeVehicle.battery2
}
}
return activeVehicle.battery
}
return null
}
function getBatteryColor(battery) {
if(battery) {
if(battery.percentRemaining.value > 75) {
return qgcPal.text
}
if(battery.percentRemaining.value > 50) {
return qgcPal.colorOrange
}
if(battery.percentRemaining.value > 0.1) {
return qgcPal.colorRed
}
}
return qgcPal.colorGrey
}
function getBatteryPercentageText(battery) {
if(battery) {
if(battery.percentRemaining.value > 98.9) {
return "100%"
}
if(battery.percentRemaining.value > 0.1) {
return battery.percentRemaining.valueString + battery.percentRemaining.units
}
if(battery.voltage.value >= 0) {
return battery.voltage.valueString + battery.voltage.units
}
}
return "N/A"
}
Component {
id: batteryInfo
Rectangle {
width: battCol.width + ScreenTools.defaultFontPixelWidth * 3
height: battCol.height + ScreenTools.defaultFontPixelHeight * 2
radius: ScreenTools.defaultFontPixelHeight * 0.5
color: qgcPal.window
Column {
id: battCol
spacing: ScreenTools.defaultFontPixelHeight * 0.5
width: Math.max(battGrid.width, battLabel.width)
anchors.margins: ScreenTools.defaultFontPixelHeight
anchors.centerIn: parent
QGCLabel {
id: battLabel
text: qsTr("Battery Status")
font.family: ScreenTools.demiboldFontFamily
anchors.horizontalCenter: parent.horizontalCenter
}
GridLayout {
id: battGrid
anchors.margins: ScreenTools.defaultFontPixelHeight
columnSpacing: ScreenTools.defaultFontPixelWidth
columns: 2
anchors.horizontalCenter: parent.horizontalCenter
QGCLabel {
id: batteryLabel
text: qsTr("Battery 1")
Layout.alignment: Qt.AlignVCenter
}
QGCColoredImage {
height: batteryLabel.height
width: height
sourceSize.width: width
source: "/qmlimages/Battery.svg"
color: qgcPal.text
fillMode: Image.PreserveAspectFit
Rectangle {
color: getBatteryColor(activeVehicle ? activeVehicle.battery : null)
anchors.left: parent.left
anchors.leftMargin: ScreenTools.defaultFontPixelWidth * 0.125
height: parent.height * 0.35
width: activeVehicle ? (activeVehicle.battery.percentRemaining.value / 100) * parent.width * 0.875 : 0
anchors.verticalCenter: parent.verticalCenter
}
}
QGCLabel { text: qsTr("Voltage:") }
QGCLabel { text: (battery1 && battery1.voltage.value !== -1) ? (battery1.voltage.valueString + " " + battery1.voltage.units) : "N/A" }
QGCLabel { text: qsTr("Accumulated Consumption:") }
QGCLabel { text: (battery1 && battery1.mahConsumed.value !== -1) ? (battery1.mahConsumed.valueString + " " + battery1.mahConsumed.units) : "N/A" }
Item {
width: 1
height: 1
visible: hasSecondBattery;
Layout.columnSpan: 2
}
QGCLabel {
text: qsTr("Battery 2")
visible: hasSecondBattery
Layout.alignment: Qt.AlignVCenter
}
QGCColoredImage {
height: batteryLabel.height
width: height
sourceSize.width: width
source: "/qmlimages/Battery.svg"
color: qgcPal.text
visible: hasSecondBattery
fillMode: Image.PreserveAspectFit
Rectangle {
color: getBatteryColor(activeVehicle ? activeVehicle.battery2 : null)
anchors.left: parent.left
anchors.leftMargin: ScreenTools.defaultFontPixelWidth * 0.125
height: parent.height * 0.35
width: activeVehicle ? (activeVehicle.battery2.percentRemaining.value / 100) * parent.width * 0.875 : 0
anchors.verticalCenter: parent.verticalCenter
}
}
QGCLabel { text: qsTr("Voltage:"); visible: hasSecondBattery; }
QGCLabel { text: (battery2 && battery2.voltage.value !== -1) ? (battery2.voltage.valueString + " " + battery2.voltage.units) : "N/A"; visible: hasSecondBattery; }
QGCLabel { text: qsTr("Accumulated Consumption:"); visible: hasSecondBattery; }
QGCLabel { text: (battery2 && battery2.mahConsumed.value !== -1) ? (battery2.mahConsumed.valueString + " " + battery2.mahConsumed.units) : "N/A"; visible: hasSecondBattery; }
}
}
}
}
Row {
id: batteryIndicatorRow
anchors.top: parent.top
anchors.bottom: parent.bottom
opacity: (activeVehicle && activeVehicle.battery.voltage.value >= 0) ? 1 : 0.5
spacing: ScreenTools.defaultFontPixelWidth
QGCColoredImage {
anchors.top: parent.top
anchors.bottom: parent.bottom
width: height
sourceSize.width: width
source: "/qmlimages/Battery.svg"
color: qgcPal.text
fillMode: Image.PreserveAspectFit
Rectangle {
color: getBatteryColor(lowestBattery())
anchors.left: parent.left
anchors.leftMargin: ScreenTools.defaultFontPixelWidth * 0.25
height: parent.height * 0.35
width: activeVehicle ? (activeVehicle.battery.percentRemaining.value / 100) * parent.width * 0.75 : 0
anchors.verticalCenter: parent.verticalCenter
}
}
QGCLabel {
text: getBatteryPercentageText(lowestBattery())
font.pointSize: ScreenTools.smallFontPointSize
color: getBatteryColor(lowestBattery())
anchors.verticalCenter: parent.verticalCenter
}
}
MouseArea {
anchors.fill: parent
onClicked: {
mainWindow.showPopUp(_root, batteryInfo)
}
}
}
/****************************************************************************
*
* (c) 2009-2019 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
* @file
* @author Gus Grubba <gus@auterion.com>
*/
import QtQuick 2.11
import QtQuick.Controls 1.4
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
import Custom.Widgets 1.0
//-------------------------------------------------------------------------
//-- GPS Indicator
Item {
id: _root
width: gpsRow.width
anchors.top: parent.top
anchors.bottom: parent.bottom
function getGPSSignal() {
if(!activeVehicle || activeVehicle.gps.count.rawValue < 1 || activeVehicle.gps.hdop.rawValue > 1.4) {
return 0;
} else if(activeVehicle.gps.hdop.rawValue < 1.0) {
return 100;
} else if(activeVehicle.gps.hdop.rawValue < 1.1) {
return 75;
} else if(activeVehicle.gps.hdop.rawValue < 1.2) {
return 50;
} else {
return 25;
}
}
Component {
id: gpsInfo
Rectangle {
width: gpsCol.width + ScreenTools.defaultFontPixelWidth * 3
height: gpsCol.height + ScreenTools.defaultFontPixelHeight * 2
radius: ScreenTools.defaultFontPixelHeight * 0.5
color: qgcPal.window
Column {
id: gpsCol
spacing: ScreenTools.defaultFontPixelHeight * 0.5
width: Math.max(gpsGrid.width, gpsLabel.width)
anchors.margins: ScreenTools.defaultFontPixelHeight
anchors.centerIn: parent
QGCLabel {
id: gpsLabel
text: (activeVehicle && activeVehicle.gps.count.value >= 0) ? qsTr("GPS Status") : qsTr("GPS Data Unavailable")
font.family: ScreenTools.demiboldFontFamily
anchors.horizontalCenter: parent.horizontalCenter
}
GridLayout {
id: gpsGrid
visible: (activeVehicle && activeVehicle.gps.count.value >= 0)
anchors.margins: ScreenTools.defaultFontPixelHeight
columnSpacing: ScreenTools.defaultFontPixelWidth
anchors.horizontalCenter: parent.horizontalCenter
columns: 2
QGCLabel { text: qsTr("GPS Count:") }
QGCLabel { text: activeVehicle ? activeVehicle.gps.count.valueString : qsTr("N/A", "No data to display") }
QGCLabel { text: qsTr("GPS Lock:") }
QGCLabel { text: activeVehicle ? activeVehicle.gps.lock.enumStringValue : qsTr("N/A", "No data to display") }
QGCLabel { text: qsTr("HDOP:") }
QGCLabel { text: activeVehicle ? activeVehicle.gps.hdop.valueString : qsTr("--.--", "No data to display") }
QGCLabel { text: qsTr("VDOP:") }
QGCLabel { text: activeVehicle ? activeVehicle.gps.vdop.valueString : qsTr("--.--", "No data to display") }
QGCLabel { text: qsTr("Course Over Ground:") }
QGCLabel { text: activeVehicle ? activeVehicle.gps.courseOverGround.valueString : qsTr("--.--", "No data to display") }
}
}
}
}
Row {
id: gpsRow
anchors.top: parent.top
anchors.bottom: parent.bottom
spacing: ScreenTools.defaultFontPixelWidth * 0.25
QGCColoredImage {
width: height
anchors.top: parent.top
anchors.bottom: parent.bottom
sourceSize.height: height
source: "/qmlimages/Gps.svg"
color: qgcPal.text
fillMode: Image.PreserveAspectFit
opacity: getGPSSignal() > 0 ? 1 : 0.5
}
CustomSignalStrength {
anchors.verticalCenter: parent.verticalCenter
size: parent.height * 0.75
percent: getGPSSignal()
}
}
MouseArea {
anchors.fill: parent
onClicked: {
mainWindow.showPopUp(_root, gpsInfo)
}
}
}
This diff is collapsed.
/****************************************************************************
*
* (c) 2009-2019 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
* @file
* @author Gus Grubba <gus@auterion.com>
*/
import QtQuick 2.11
import QtQuick.Controls 2.4
import QtQuick.Dialogs 1.3
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
Item {
anchors.fill: parent
readonly property real _indicatorMargins: ScreenTools.defaultFontPixelHeight * 0.75
//-------------------------------------------------------------------------
//-- Waiting for a vehicle
Row {
id: waitForVehicle
spacing: ScreenTools.defaultFontPixelWidth
visible: !activeVehicle
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: parent.left
QGCColoredImage {
id: menuEdge
anchors.verticalCenter: parent.verticalCenter
height: ScreenTools.defaultFontPixelHeight
width: height
sourceSize.height: parent.height
fillMode: Image.PreserveAspectFit
source: "/qmlimages/PaperPlane.svg"
color: qgcPal.buttonText
}
QGCLabel {
anchors.verticalCenter: parent.verticalCenter
text: qsTr("Waiting for a vehicle")
font.pointSize: ScreenTools.mediumFontPointSize
font.family: ScreenTools.demiboldFontFamily
}
}
//-------------------------------------------------------------------------
//-- Toolbar Indicators
Row {
id: indicatorRow
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.rightMargin: ScreenTools.defaultFontPixelWidth * 2
spacing: ScreenTools.defaultFontPixelWidth * 2
visible: activeVehicle && !communicationLost
Repeater {
model: activeVehicle ? activeVehicle.toolBarIndicators : []
Loader {
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.margins: _indicatorMargins
source: modelData;
}
}
Item {
width: 1
height: 1
}
Loader {
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.margins: _indicatorMargins
source: "/toolbar/MessageIndicator.qml"
}
}
}
/****************************************************************************
*
* (c) 2009-2019 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
* @file
* @author Gus Grubba <gus@auterion.com>
*/
import QtQuick 2.11
import QtQuick.Controls 1.4
import QGroundControl 1.0
import QGroundControl.Controls 1.0
import QGroundControl.MultiVehicleManager 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.Palette 1.0
//-------------------------------------------------------------------------
//-- Mode Indicator
Item {
anchors.top: parent.top
anchors.bottom: parent.bottom
width: selectorRow.width
property var _flightModes: activeVehicle ? activeVehicle.flightModes : [ ]
on_FlightModesChanged: flightModeSelector.updateFlightModesMenu()
Row {
id: selectorRow
spacing: ScreenTools.defaultFontPixelWidth
anchors.verticalCenter: parent.verticalCenter
QGCLabel {
id: flightModeSelector
text: activeVehicle ? activeVehicle.flightMode : qsTr("N/A")
color: qgcPal.text
font.pointSize: ScreenTools.defaultFontPointSize
anchors.verticalCenter: parent.verticalCenter
Menu {
id: flightModesMenu
}
Component {
id: flightModeMenuItemComponent
MenuItem {
onTriggered: activeVehicle.flightMode = text
}
}
property var flightModesMenuItems: []
function updateFlightModesMenu() {
if (activeVehicle && activeVehicle.flightModeSetAvailable) {
// Remove old menu items
var i = 0
for (i = 0; i < flightModesMenuItems.length; i++) {
flightModesMenu.removeItem(flightModesMenuItems[i])
}
flightModesMenuItems.length = 0
// Add new items
for (i = 0; i < _flightModes.length; i++) {
var menuItem = flightModeMenuItemComponent.createObject(null, { "text": _flightModes[i] })
flightModesMenuItems.push(menuItem)
flightModesMenu.insertItem(i, menuItem)
}
}
}
}
QGCColoredImage {
anchors.verticalCenter: parent.verticalCenter
height: ScreenTools.defaultFontPixelHeight * 0.5
width: height
sourceSize.height: parent.height
fillMode: Image.PreserveAspectFit
source: "/res/DropArrow.svg"
color: qgcPal.text
}
}
Component.onCompleted: flightModeSelector.updateFlightModesMenu()
MouseArea {
visible: activeVehicle && activeVehicle.flightModeSetAvailable
anchors.fill: parent
onClicked: flightModesMenu.popup()
}
}
/****************************************************************************
*
* (c) 2009-2019 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
* @file
* @author Gus Grubba <gus@auterion.com>
*/
import QtQuick 2.11
import QtQuick.Controls 1.4
import QGroundControl 1.0
import QGroundControl.Controls 1.0
import QGroundControl.MultiVehicleManager 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.Palette 1.0
//-------------------------------------------------------------------------
//-- Multi Vehicle Selector
Item {
anchors.top: parent.top
anchors.bottom: parent.bottom
width: selectorRow.width
property bool _multiVehicles: QGroundControl.multiVehicleManager.vehicles.count > 1
Component.onCompleted: {
updatemultiVehiclesMenu()
}
Connections {
target: QGroundControl.multiVehicleManager.vehicles
onCountChanged: updatemultiVehiclesMenu()
}
Row {
id: selectorRow
spacing: ScreenTools.defaultFontPixelWidth
anchors.verticalCenter: parent.verticalCenter
QGCColoredImage {
anchors.verticalCenter: parent.verticalCenter
height: ScreenTools.defaultFontPixelHeight
width: height
sourceSize.height: parent.height
fillMode: Image.PreserveAspectFit
source: "/qmlimages/PaperPlane.svg"
color: qgcPal.text
}
QGCLabel {
id: multiVehicleSelector
text: "Vehicle " + (activeVehicle ? activeVehicle.id : "None")
color: qgcPal.buttonText
anchors.verticalCenter: parent.verticalCenter
}
QGCColoredImage {
visible: _multiVehicles
anchors.verticalCenter: parent.verticalCenter
height: ScreenTools.defaultFontPixelHeight * 0.5
width: height
sourceSize.height: parent.height
fillMode: Image.PreserveAspectFit
source: "/res/DropArrow.svg"
color: qgcPal.text
}
}
Menu {
id: multiVehiclesMenu
}
Component {
id: multiVehicleMenuItemComponent
MenuItem {
onTriggered: QGroundControl.multiVehicleManager.activeVehicle = vehicle
property int vehicleId: Number(text.split(" ")[1])
property var vehicle: QGroundControl.multiVehicleManager.getVehicleById(vehicleId)
}
}
property var multiVehiclesMenuItems: []
function updatemultiVehiclesMenu() {
if (_multiVehicles) {
// Remove old menu items
for (var i = 0; i < multiVehiclesMenuItems.length; i++) {
multiVehiclesMenu.removeItem(multiVehiclesMenuItems[i])
}
multiVehiclesMenuItems.length = 0
// Add new items
for (i = 0; i < QGroundControl.multiVehicleManager.vehicles.count; i++) {
var vehicle = QGroundControl.multiVehicleManager.vehicles.get(i)
var menuItem = multiVehicleMenuItemComponent.createObject(null, { "text": "Vehicle " + vehicle.id })
multiVehiclesMenuItems.push(menuItem)
multiVehiclesMenu.insertItem(i, menuItem)
console.log("Vehicle " + vehicle.id)
}
} else {
console.log('No multiple vehicles: ' + QGroundControl.multiVehicleManager.vehicles.count)
}
}
MouseArea {
visible: _multiVehicles
anchors.fill: parent
onClicked: {
console.log('Clicked')
multiVehiclesMenu.popup()
}
}
}
/****************************************************************************
*
* (c) 2009-2019 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
* @file
* @author Gus Grubba <gus@auterion.com>
*/
import QtQuick 2.11
import QtQuick.Controls 1.4
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
import Custom.Widgets 1.0
//-------------------------------------------------------------------------
//-- RC RSSI Indicator
Item {
id: _root
width: visible ? rssiRow.width : 0
anchors.top: parent.top
anchors.bottom: parent.bottom
visible: activeVehicle ? activeVehicle.supportsRadio : true
property bool _rcRSSIAvailable: activeVehicle ? activeVehicle.rcRSSI > 0 && activeVehicle.rcRSSI <= 100 : false
Component {
id: rcRSSIInfo
Rectangle {
width: rcrssiCol.width + ScreenTools.defaultFontPixelWidth * 3
height: rcrssiCol.height + ScreenTools.defaultFontPixelHeight * 2
radius: ScreenTools.defaultFontPixelHeight * 0.5
color: qgcPal.window
Column {
id: rcrssiCol
spacing: ScreenTools.defaultFontPixelHeight * 0.5
width: Math.max(rcrssiGrid.width, rssiLabel.width)
anchors.margins: ScreenTools.defaultFontPixelHeight
anchors.centerIn: parent
QGCLabel {
id: rssiLabel
text: activeVehicle ? (activeVehicle.rcRSSI !== 255 ? qsTr("RC RSSI Status") : qsTr("RC RSSI Data Unavailable")) : qsTr("N/A", "No data available")
font.family: ScreenTools.demiboldFontFamily
anchors.horizontalCenter: parent.horizontalCenter
}
GridLayout {
id: rcrssiGrid
visible: _rcRSSIAvailable
anchors.margins: ScreenTools.defaultFontPixelHeight
columnSpacing: ScreenTools.defaultFontPixelWidth
columns: 2
anchors.horizontalCenter: parent.horizontalCenter
QGCLabel { text: qsTr("RSSI:") }
QGCLabel { text: activeVehicle ? (activeVehicle.rcRSSI + "%") : 0 }
}
}
}
}
Row {
id: rssiRow
anchors.top: parent.top
anchors.bottom: parent.bottom
spacing: ScreenTools.defaultFontPixelWidth * 0.25
QGCColoredImage {
width: height
anchors.top: parent.top
anchors.bottom: parent.bottom
sourceSize.height: height
source: "/custom/img/menu_rc.svg"
color: qgcPal.text
fillMode: Image.PreserveAspectFit
opacity: _rcRSSIAvailable ? 1 : 0.5
}
CustomSignalStrength {
anchors.verticalCenter: parent.verticalCenter
size: parent.height * 0.75
percent: _rcRSSIAvailable ? activeVehicle.rcRSSI : 0
}
}
MouseArea {
anchors.fill: parent
onClicked: {
mainWindow.showPopUp(_root, rcRSSIInfo)
}
}
}
/****************************************************************************
*
* (c) 2009-2019 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
* @file
* @brief Custom Autopilot Plugin
* @author Gus Grubba <gus@auterion.com>
*/
#include "CustomAutoPilotPlugin.h"
#include "QGCApplication.h"
#include "QGCCorePlugin.h"
//-----------------------------------------------------------------------------
CustomAutoPilotPlugin::CustomAutoPilotPlugin(Vehicle* vehicle, QObject* parent)
: PX4AutoPilotPlugin(vehicle, parent)
{
connect(qgcApp()->toolbox()->corePlugin(), &QGCCorePlugin::showAdvancedUIChanged, this, &CustomAutoPilotPlugin::_advancedChanged);
}
//-----------------------------------------------------------------------------
void
CustomAutoPilotPlugin::_advancedChanged(bool)
{
_components.clear();
emit vehicleComponentsChanged();
}
//-----------------------------------------------------------------------------
const QVariantList&
CustomAutoPilotPlugin::vehicleComponents()
{
if (_components.count() == 0 && !_incorrectParameterVersion) {
if (_vehicle) {
bool showAdvanced = qgcApp()->toolbox()->corePlugin()->showAdvancedUI();
qDebug() << "Loading components:" << showAdvanced;
if (_vehicle->parameterManager()->parametersReady()) {
if(showAdvanced) {
_airframeComponent = new AirframeComponent(_vehicle, this);
_airframeComponent->setupTriggerSignals();
_components.append(QVariant::fromValue(reinterpret_cast<VehicleComponent*>(_airframeComponent)));
}
if (!_vehicle->hilMode()) {
_sensorsComponent = new SensorsComponent(_vehicle, this);
_sensorsComponent->setupTriggerSignals();
_components.append(QVariant::fromValue(reinterpret_cast<VehicleComponent*>(_sensorsComponent)));
}
if(showAdvanced) {
_radioComponent = new PX4RadioComponent(_vehicle, this);
_radioComponent->setupTriggerSignals();
_components.append(QVariant::fromValue(reinterpret_cast<VehicleComponent*>(_radioComponent)));
_flightModesComponent = new FlightModesComponent(_vehicle, this);
_flightModesComponent->setupTriggerSignals();
_components.append(QVariant::fromValue(reinterpret_cast<VehicleComponent*>(_flightModesComponent)));
_powerComponent = new PowerComponent(_vehicle, this);
_powerComponent->setupTriggerSignals();
_components.append(QVariant::fromValue(reinterpret_cast<VehicleComponent*>(_powerComponent)));
_motorComponent = new MotorComponent(_vehicle, this);
_motorComponent->setupTriggerSignals();
_components.append(QVariant::fromValue(reinterpret_cast<VehicleComponent*>(_motorComponent)));
}
_safetyComponent = new SafetyComponent(_vehicle, this);
_safetyComponent->setupTriggerSignals();
_components.append(QVariant::fromValue(reinterpret_cast<VehicleComponent*>(_safetyComponent)));
if(showAdvanced) {
_tuningComponent = new PX4TuningComponent(_vehicle, this);
_tuningComponent->setupTriggerSignals();
_components.append(QVariant::fromValue(reinterpret_cast<VehicleComponent*>(_tuningComponent)));
//-- Is there support for cameras?
if(_vehicle->parameterManager()->parameterExists(_vehicle->id(), "TRIG_MODE")) {
_cameraComponent = new CameraComponent(_vehicle, this);
_cameraComponent->setupTriggerSignals();
_components.append(QVariant::fromValue(reinterpret_cast<VehicleComponent*>(_cameraComponent)));
}
}
//-- Is there an ESP8266 Connected?
if(_vehicle->parameterManager()->parameterExists(MAV_COMP_ID_UDP_BRIDGE, "SW_VER")) {
_esp8266Component = new ESP8266Component(_vehicle, this);
_esp8266Component->setupTriggerSignals();
_components.append(QVariant::fromValue(reinterpret_cast<VehicleComponent*>(_esp8266Component)));
}
} else {
qWarning() << "Call to vehicleCompenents prior to parametersReady";
}
if(_vehicle->parameterManager()->parameterExists(_vehicle->id(), "SLNK_RADIO_CHAN")) {
_syslinkComponent = new SyslinkComponent(_vehicle, this);
_syslinkComponent->setupTriggerSignals();
_components.append(QVariant::fromValue(reinterpret_cast<VehicleComponent*>(_syslinkComponent)));
}
} else {
qWarning() << "Internal error";
}
}
return _components;
}
/****************************************************************************
*
* (c) 2009-2019 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
* @file
* @brief Custom Autopilot Plugin
* @author Gus Grubba <gus@auterion.com>
*/
#pragma once
#include "PX4AutoPilotPlugin.h"
#include "Vehicle.h"
/// Custom overrides from standard PX4AutoPilotPlugin implementation
class CustomAutoPilotPlugin : public PX4AutoPilotPlugin
{
Q_OBJECT
public:
CustomAutoPilotPlugin(Vehicle* vehicle, QObject* parent);
const QVariantList& vehicleComponents() override;
private slots:
void _advancedChanged (bool advanced);
private:
QVariantList _components;
};
This diff is collapsed.
/****************************************************************************
*
* (c) 2009-2019 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
* @brief Custom QGCCorePlugin Declaration
* @author Gus Grubba <gus@auterion.com>
*/
#pragma once
#include "QGCCorePlugin.h"
#include "QGCOptions.h"
#include "QGCLoggingCategory.h"
#include "VideoReceiver.h"
#include "SettingsManager.h"
#include <QTranslator>
class CustomPlugin;
class CustomSettings;
Q_DECLARE_LOGGING_CATEGORY(CustomLog)
//-- Our own, custom video receiver
class CustomVideoReceiver : public VideoReceiver
{
Q_OBJECT
public:
explicit CustomVideoReceiver(QObject* parent = nullptr);
~CustomVideoReceiver();
};
//-----------------------------------------------------------------------------
//-- Our own, custom options
class CustomOptions : public QGCOptions
{
public:
CustomOptions(CustomPlugin*, QObject* parent = nullptr);
bool wifiReliableForCalibration () const final { return true; }
QUrl flyViewOverlay () const final { return QUrl::fromUserInput("qrc:/custom/CustomFlyView.qml"); }
//-- We have our own toolbar
QUrl mainToolbarUrl () const final { return QUrl::fromUserInput("qrc:/custom/CustomMainToolBar.qml"); }
QUrl planToolbarUrl () const final { return QUrl::fromUserInput("qrc:/custom/CustomMainToolBar.qml"); }
//-- Don't show instrument widget
CustomInstrumentWidget* instrumentWidget () final { return nullptr; }
bool showMavlinkLogOptions () const final { return false; }
bool showFirmwareUpgrade () const final;
//-- We handle multiple vehicles in a custom way
bool enableMultiVehicleList () const final { return false; }
//-- We handle our own map scale
bool enableMapScale () const final { return false; }
// TODO: Can't access QGCPalette without some workarounds, change this upstream
QColor toolbarBackgroundLight () const final;
QColor toolbarBackgroundDark () const final;
};
//-----------------------------------------------------------------------------
class CustomPlugin : public QGCCorePlugin
{
Q_OBJECT
public:
CustomPlugin(QGCApplication* app, QGCToolbox *toolbox);
~CustomPlugin();
// Overrides from QGCCorePlugin
QVariantList& settingsPages () final;
QGCOptions* options () final;
QString brandImageIndoor () const final;
QString brandImageOutdoor () const final;
bool overrideSettingsGroupVisibility (QString name) final;
VideoReceiver* createVideoReceiver (QObject* parent) final;
QQmlApplicationEngine* createRootWindow (QObject* parent) final;
bool adjustSettingMetaData (const QString& settingsGroup, FactMetaData& metaData) final;
void paletteOverride (QString colorName, QGCPalette::PaletteColorInfo_t& colorInfo) final;
// Overrides from QGCTool
void setToolbox (QGCToolbox* toolbox);
const static QColor _windowShadeEnabledLightColor;
const static QColor _windowShadeEnabledDarkColor;
private slots:
void _advancedChanged (bool advanced);
private:
void
addSettingsEntry(
const QString& title,
const char* qmlFile,
const char* iconFile = nullptr);
private:
CustomOptions* _pOptions = nullptr;
QVariantList _customSettingsList; // Not to be mixed up with QGCCorePlugin implementation
};
/****************************************************************************
*
* (c) 2009-2019 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
* @file
* @brief Custom QtQuick Interface
* @author Gus Grubba <gus@auterion.com>
*/
#include "QGCApplication.h"
#include "AppSettings.h"
#include "SettingsManager.h"
#include "MAVLinkLogManager.h"
#include "QGCMapEngine.h"
#include "QGCApplication.h"
#include "PositionManager.h"
#include "CustomPlugin.h"
#include "CustomQuickInterface.h"
#include <QDirIterator>
#include <QtAlgorithms>
//-----------------------------------------------------------------------------
CustomQuickInterface::CustomQuickInterface(QObject* parent)
: QObject(parent)
{
qCDebug(CustomLog) << "CustomQuickInterface Created";
}
//-----------------------------------------------------------------------------
CustomQuickInterface::~CustomQuickInterface()
{
qCDebug(CustomLog) << "CustomQuickInterface Destroyed";
}
//-----------------------------------------------------------------------------
void
CustomQuickInterface::init()
{
}
/****************************************************************************
*
* (c) 2009-2019 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
* @file
* @brief Custom QtQuick Interface
* @author Gus Grubba <gus@auterion.com>
*/
#pragma once
#include "Vehicle.h"
#include <QObject>
#include <QTimer>
#include <QColor>
#include <QGeoPositionInfo>
#include <QGeoPositionInfoSource>
//-----------------------------------------------------------------------------
// QtQuick Interface (UI)
class CustomQuickInterface : public QObject
{
Q_OBJECT
public:
CustomQuickInterface(QObject* parent = nullptr);
~CustomQuickInterface();
void init ();
};
/****************************************************************************
*
* (c) 2009-2019 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
* @file
* @brief Camera Controller
* @author Gus Grubba <gus@auterion.com>
*
*/
#include "CustomCameraControl.h"
#include "QGCCameraIO.h"
QGC_LOGGING_CATEGORY(CustomCameraLog, "CustomCameraLog")
QGC_LOGGING_CATEGORY(CustomCameraVerboseLog, "CustomCameraVerboseLog")
//-----------------------------------------------------------------------------
CustomCameraControl::CustomCameraControl(const mavlink_camera_information_t *info, Vehicle* vehicle, int compID, QObject* parent)
: QGCCameraControl(info, vehicle, compID, parent)
{
connect(_vehicle, &Vehicle::mavlinkMessageReceived, this, &CustomCameraControl::_mavlinkMessageReceived);
}
//-----------------------------------------------------------------------------
bool
CustomCameraControl::takePhoto()
{
bool res = false;
res = QGCCameraControl::takePhoto();
return res;
}
//-----------------------------------------------------------------------------
bool
CustomCameraControl::stopTakePhoto()
{
bool res = QGCCameraControl::stopTakePhoto();
return res;
}
//-----------------------------------------------------------------------------
bool
CustomCameraControl::startVideo()
{
bool res = QGCCameraControl::startVideo();
return res;
}
//-----------------------------------------------------------------------------
bool
CustomCameraControl::stopVideo()
{
bool res = QGCCameraControl::stopVideo();
return res;
}
//-----------------------------------------------------------------------------
void
CustomCameraControl::setVideoMode()
{
if(cameraMode() != CAM_MODE_VIDEO) {
qCDebug(CustomCameraLog) << "setVideoMode()";
Fact* pFact = getFact(kCAM_MODE);
if(pFact) {
pFact->setRawValue(CAM_MODE_VIDEO);
_setCameraMode(CAM_MODE_VIDEO);
}
}
}
//-----------------------------------------------------------------------------
void
CustomCameraControl::setPhotoMode()
{
if(cameraMode() != CAM_MODE_PHOTO) {
qCDebug(CustomCameraLog) << "setPhotoMode()";
Fact* pFact = getFact(kCAM_MODE);
if(pFact) {
pFact->setRawValue(CAM_MODE_PHOTO);
_setCameraMode(CAM_MODE_PHOTO);
}
}
}
//-----------------------------------------------------------------------------
void
CustomCameraControl::_setVideoStatus(VideoStatus status)
{
QGCCameraControl::_setVideoStatus(status);
}
//-----------------------------------------------------------------------------
void
CustomCameraControl::_mavlinkMessageReceived(const mavlink_message_t& message)
{
switch (message.msgid) {
case MAVLINK_MSG_ID_MOUNT_ORIENTATION:
_handleGimbalOrientation(message);
break;
}
}
//-----------------------------------------------------------------------------
void
CustomCameraControl::_handleGimbalOrientation(const mavlink_message_t& message)
{
mavlink_mount_orientation_t o;
mavlink_msg_mount_orientation_decode(&message, &o);
if(fabsf(_gimbalRoll - o.roll) > 0.5f) {
_gimbalRoll = o.roll;
emit gimbalRollChanged();
}
if(fabsf(_gimbalPitch - o.pitch) > 0.5f) {
_gimbalPitch = o.pitch;
emit gimbalPitchChanged();
}
if(fabsf(_gimbalYaw - o.yaw) > 0.5f) {
_gimbalYaw = o.yaw;
emit gimbalYawChanged();
}
if(!_gimbalData) {
_gimbalData = true;
emit gimbalDataChanged();
}
}
//-----------------------------------------------------------------------------
void
CustomCameraControl::handleCaptureStatus(const mavlink_camera_capture_status_t& cap)
{
QGCCameraControl::handleCaptureStatus(cap);
}
/****************************************************************************
*
* (c) 2009-2019 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
* @file
* @brief Camera Controller
* @author Gus Grubba <gus@auterion.com>
*
*/
#pragma once
#include "QGCCameraControl.h"
#include <QSize>
#include <QPoint>
Q_DECLARE_LOGGING_CATEGORY(CustomCameraLog)
Q_DECLARE_LOGGING_CATEGORY(CustomCameraVerboseLog)
//-----------------------------------------------------------------------------
class CustomCameraControl : public QGCCameraControl
{
Q_OBJECT
public:
CustomCameraControl(const mavlink_camera_information_t* info, Vehicle* vehicle, int compID, QObject* parent = nullptr);
Q_PROPERTY(qreal gimbalRoll READ gimbalRoll NOTIFY gimbalRollChanged)
Q_PROPERTY(qreal gimbalPitch READ gimbalPitch NOTIFY gimbalPitchChanged)
Q_PROPERTY(qreal gimbalYaw READ gimbalYaw NOTIFY gimbalYawChanged)
Q_PROPERTY(bool gimbalData READ gimbalData NOTIFY gimbalDataChanged)
bool takePhoto () override;
bool stopTakePhoto () override;
bool startVideo () override;
bool stopVideo () override;
void setVideoMode () override;
void setPhotoMode () override;
void handleCaptureStatus (const mavlink_camera_capture_status_t& capStatus) override;
qreal gimbalRoll () { return static_cast<qreal>(_gimbalRoll);}
qreal gimbalPitch () { return static_cast<qreal>(_gimbalPitch); }
qreal gimbalYaw () { return static_cast<qreal>(_gimbalYaw); }
bool gimbalData () { return _gimbalData; }
private slots:
void _mavlinkMessageReceived (const mavlink_message_t& message);
signals:
void gimbalRollChanged ();
void gimbalPitchChanged ();
void gimbalYawChanged ();
void gimbalDataChanged ();
protected:
void _setVideoStatus (VideoStatus status) override;
private:
void _handleGimbalOrientation(const mavlink_message_t& message);
private:
float _gimbalRoll = 0.0;
float _gimbalPitch = 0.0;
float _gimbalYaw = 0.0;
bool _gimbalData = false;
};
/****************************************************************************
*
* (c) 2009-2019 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
* @file
* @brief Camera Controller
* @author Gus Grubba <gus@auterion.com>
*
*/
#include "QGCApplication.h"
#include "CustomCameraManager.h"
//-----------------------------------------------------------------------------
CustomCameraManager::CustomCameraManager(Vehicle *vehicle)
: QGCCameraManager(vehicle)
{
}
/****************************************************************************
*
* (c) 2009-2019 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
* @file
* @brief Camera Controller
* @author Gus Grubba <gus@auterion.com>
*
*/
#pragma once
#include "QGCCameraManager.h"
//-----------------------------------------------------------------------------
class CustomCameraManager : public QGCCameraManager
{
Q_OBJECT
public:
CustomCameraManager(Vehicle* vehicle);
};
/****************************************************************************
*
* (c) 2009-2019 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
* @file
* @brief Custom Firmware Plugin (PX4)
* @author Gus Grubba <gus@auterion.com>
*
*/
#include "CustomFirmwarePlugin.h"
#include "CustomAutoPilotPlugin.h"
#include "CustomCameraManager.h"
#include "CustomCameraControl.h"
//-----------------------------------------------------------------------------
CustomFirmwarePlugin::CustomFirmwarePlugin()
{
}
//-----------------------------------------------------------------------------
AutoPilotPlugin* CustomFirmwarePlugin::autopilotPlugin(Vehicle* vehicle)
{
return new CustomAutoPilotPlugin(vehicle, vehicle);
}
//-----------------------------------------------------------------------------
QGCCameraManager*
CustomFirmwarePlugin::createCameraManager(Vehicle *vehicle)
{
return new CustomCameraManager(vehicle);
}
//-----------------------------------------------------------------------------
QGCCameraControl*
CustomFirmwarePlugin::createCameraControl(const mavlink_camera_information_t* info, Vehicle *vehicle, int compID, QObject* parent)
{
return new CustomCameraControl(info, vehicle, compID, parent);
}
//-----------------------------------------------------------------------------
const QVariantList&
CustomFirmwarePlugin::toolBarIndicators(const Vehicle* vehicle)
{
Q_UNUSED(vehicle);
if(_toolBarIndicatorList.size() == 0) {
_toolBarIndicatorList.append(QVariant::fromValue(QUrl::fromUserInput("qrc:/toolbar/GPSIndicator.qml")));
_toolBarIndicatorList.append(QVariant::fromValue(QUrl::fromUserInput("qrc:/toolbar/TelemetryRSSIIndicator.qml")));
_toolBarIndicatorList.append(QVariant::fromValue(QUrl::fromUserInput("qrc:/toolbar/RCRSSIIndicator.qml")));
_toolBarIndicatorList.append(QVariant::fromValue(QUrl::fromUserInput("qrc:/toolbar/BatteryIndicator.qml")));
}
return _toolBarIndicatorList;
}
/****************************************************************************
*
* (c) 2009-2019 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
* @file
* @brief Custom Firmware Plugin (PX4)
* @author Gus Grubba <gus@auterion.com>
*
*/
#pragma once
#include "FirmwarePlugin.h"
#include "PX4FirmwarePlugin.h"
class CustomCameraManager;
class CustomFirmwarePlugin : public PX4FirmwarePlugin
{
Q_OBJECT
public:
CustomFirmwarePlugin();
// FirmwarePlugin overrides
AutoPilotPlugin* autopilotPlugin (Vehicle* vehicle) override;
QGCCameraManager* createCameraManager (Vehicle *vehicle) override;
QGCCameraControl* createCameraControl (const mavlink_camera_information_t* info, Vehicle* vehicle, int compID, QObject* parent = nullptr) override;
const QVariantList& toolBarIndicators (const Vehicle* vehicle) override;
private:
QVariantList _toolBarIndicatorList;
};
/****************************************************************************
*
* (c) 2009-2019 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
* @file
* @brief Custom Firmware Plugin Factory (PX4)
* @author Gus Grubba <gus@auterion.com>
*
*/
#include "CustomFirmwarePluginFactory.h"
#include "CustomFirmwarePlugin.h"
CustomFirmwarePluginFactory CustomFirmwarePluginFactoryImp;
CustomFirmwarePluginFactory::CustomFirmwarePluginFactory()
: _pluginInstance(nullptr)
{
}
QList<MAV_AUTOPILOT> CustomFirmwarePluginFactory::supportedFirmwareTypes() const
{
QList<MAV_AUTOPILOT> list;
list.append(MAV_AUTOPILOT_PX4);
return list;
}
FirmwarePlugin* CustomFirmwarePluginFactory::firmwarePluginForAutopilot(MAV_AUTOPILOT autopilotType, MAV_TYPE vehicleType)
{
Q_UNUSED(vehicleType);
if (autopilotType == MAV_AUTOPILOT_PX4) {
if (!_pluginInstance) {
_pluginInstance = new CustomFirmwarePlugin;
}
return _pluginInstance;
}
return nullptr;
}
/****************************************************************************
*
* (c) 2009-2019 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
* @file
* @brief Custom Firmware Plugin Factory (PX4)
* @author Gus Grubba <gus@auterion.com>
*
*/
#pragma once
#include "FirmwarePlugin.h"
class CustomFirmwarePlugin;
class CustomFirmwarePluginFactory : public FirmwarePluginFactory
{
Q_OBJECT
public:
CustomFirmwarePluginFactory();
QList<MAV_AUTOPILOT> supportedFirmwareTypes () const override;
FirmwarePlugin* firmwarePluginForAutopilot (MAV_AUTOPILOT autopilotType, MAV_TYPE vehicleType) override;
private:
CustomFirmwarePlugin* _pluginInstance;
};
extern CustomFirmwarePluginFactory CustomFirmwarePluginFactoryImp;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment