Unverified Commit ccd2a1ed authored by Don Gagne's avatar Don Gagne Committed by GitHub

Merge pull request #8657 from DonLakeFlyer/SetRCToParam

Set RC To Param support
parents eac7e5db 17313b9b
......@@ -652,6 +652,7 @@ HEADERS += \
src/QmlControls/QmlObjectListModel.h \
src/QmlControls/QGCGeoBoundingCube.h \
src/QmlControls/RCChannelMonitorController.h \
src/QmlControls/RCToParamDialogController.h \
src/QmlControls/ScreenToolsController.h \
src/QtLocationPlugin/QMLControl/QGCMapEngineManager.h \
src/Settings/ADSBVehicleManagerSettings.h \
......@@ -857,6 +858,7 @@ SOURCES += \
src/QmlControls/QmlObjectListModel.cc \
src/QmlControls/QGCGeoBoundingCube.cc \
src/QmlControls/RCChannelMonitorController.cc \
src/QmlControls/RCToParamDialogController.cc \
src/QmlControls/ScreenToolsController.cc \
src/QtLocationPlugin/QMLControl/QGCMapEngineManager.cc \
src/Settings/ADSBVehicleManagerSettings.cc \
......
......@@ -159,6 +159,7 @@
<file alias="QGroundControl/Controls/RallyPointItemEditor.qml">src/PlanView/RallyPointItemEditor.qml</file>
<file alias="QGroundControl/Controls/RallyPointMapVisuals.qml">src/PlanView/RallyPointMapVisuals.qml</file>
<file alias="QGroundControl/Controls/RCChannelMonitor.qml">src/QmlControls/RCChannelMonitor.qml</file>
<file alias="QGroundControl/Controls/RCToParamDialog.qml">src/QmlControls/RCToParamDialog.qml</file>
<file alias="QGroundControl/Controls/RoundButton.qml">src/QmlControls/RoundButton.qml</file>
<file alias="QGroundControl/Controls/SectionHeader.qml">src/QmlControls/SectionHeader.qml</file>
<file alias="QGroundControl/Controls/SetupPage.qml">src/AutoPilotPlugins/Common/SetupPage.qml</file>
......@@ -278,6 +279,7 @@
<file alias="PlanView.SettingsGroup.json">src/Settings/PlanView.SettingsGroup.json</file>
<file alias="QGCMapCircle.Facts.json">src/MissionManager/QGCMapCircle.Facts.json</file>
<file alias="RallyPoint.FactMetaData.json">src/MissionManager/RallyPoint.FactMetaData.json</file>
<file alias="RCToParamDialog.FactMetaData.json">src/QmlControls/RCToParamDialog.FactMetaData.json</file>
<file alias="RTK.SettingsGroup.json">src/Settings/RTK.SettingsGroup.json</file>
<file alias="SpeedSection.FactMetaData.json">src/MissionManager/SpeedSection.FactMetaData.json</file>
<file alias="StructureScan.SettingsGroup.json">src/MissionManager/StructureScan.SettingsGroup.json</file>
......
......@@ -34,7 +34,7 @@ Column {
property real _margins: ScreenTools.defaultFontPixelWidth / 2
property int _colMax: 4
property bool _settingsUnlocked: false
property var _valueDialogInstrumentValue: null
property var instrumentValue: null
property var _rgFontSizes: [ ScreenTools.defaultFontPointSize, ScreenTools.smallFontPointSize, ScreenTools.mediumFontPointSize, ScreenTools.largeFontPointSize ]
property var _rgFontSizeRatios: [ 1, ScreenTools.smallFontPointRatio, ScreenTools.mediumFontPointRatio, ScreenTools.largeFontPointRatio ]
property real _doubleDescent: ScreenTools.defaultFontDescent * 2
......@@ -79,8 +79,8 @@ Column {
property int rowIndex
onClicked: {
_valueDialogInstrumentValue = instrumentValue
mainWindow.showPopupDialog(valueDialog, qsTr("Value Display"), StandardButton.Close)
instrumentValue = instrumentValue
mainWindow.showPopupDialog(valueDialogComponent, { instrumentValue: instrumentValue })
}
}
}
......@@ -243,7 +243,7 @@ Column {
QGCButton {
Layout.fillHeight: true
Layout.minimumHeight: ScreenTools.minTouchPixels
Layout.preferredHeight: ScreenTools.minTouchPixels
Layout.preferredWidth: parent.width
text: qsTr("+")
onClicked: controller.appendColumn(rowRepeaterLayout.rowIndex)
......@@ -251,7 +251,7 @@ Column {
QGCButton {
Layout.fillHeight: true
Layout.minimumHeight: ScreenTools.minTouchPixels
Layout.preferredHeight: ScreenTools.minTouchPixels
Layout.preferredWidth: parent.width
text: qsTr("-")
enabled: index !== 0 || columnRepeater.count !== 1
......@@ -262,9 +262,9 @@ Column {
RowLayout {
width: parent.width
height: ScreenTools.defaultFontPixelWidth * 2
spacing: 1
visible: _settingsUnlocked
height: ScreenTools.defaultFontPixelWidth * 2
spacing: 1
visible: _settingsUnlocked
QGCButton {
Layout.fillWidth: true
......@@ -293,9 +293,15 @@ Column {
}
Component {
id: valueDialog
id: valueDialogComponent
QGCPopupDialog {
id: valueDisplayDialog
title: qsTr("Value Display")
buttons: StandardButton.Close
property var instrumentValue: dialogProperties.instrumentValue
GridLayout {
rowSpacing: _margins
columnSpacing: _margins
......@@ -304,52 +310,51 @@ Column {
QGCCheckBox {
id: valueCheckBox
text: qsTr("Value")
checked: _valueDialogInstrumentValue.fact
checked: instrumentValue.fact
onClicked: {
if (checked) {
_valueDialogInstrumentValue.setFact(_valueDialogInstrumentValue.factGroupNames[0], _valueDialogInstrumentValue.factValueNames[0])
instrumentValue.setFact(instrumentValue.factGroupNames[0], instrumentValue.factValueNames[0])
} else {
_valueDialogInstrumentValue.clearFact()
instrumentValue.clearFact()
}
}
}
QGCComboBox {
model: _valueDialogInstrumentValue.factGroupNames
model: instrumentValue.factGroupNames
sizeToContents: true
enabled: valueCheckBox.enabled
onModelChanged: currentIndex = find(_valueDialogInstrumentValue.factGroupName)
Component.onCompleted: currentIndex = find(_valueDialogInstrumentValue.factGroupName)
onModelChanged: currentIndex = find(instrumentValue.factGroupName)
Component.onCompleted: currentIndex = find(instrumentValue.factGroupName)
onActivated: {
_valueDialogInstrumentValue.setFact(currentText, "")
_valueDialogInstrumentValue.icon = ""
_valueDialogInstrumentValue.label = _valueDialogInstrumentValue.fact.shortDescription
instrumentValue.setFact(currentText, "")
instrumentValue.icon = ""
instrumentValue.label = instrumentValue.fact.shortDescription
}
}
QGCComboBox {
model: _valueDialogInstrumentValue.factValueNames
model: instrumentValue.factValueNames
sizeToContents: true
enabled: valueCheckBox.enabled
onModelChanged: currentIndex = _valueDialogInstrumentValue.fact ? find(_valueDialogInstrumentValue.factName) : -1
Component.onCompleted: currentIndex = _valueDialogInstrumentValue.fact ? find(_valueDialogInstrumentValue.factName) : -1
onModelChanged: currentIndex = instrumentValue.fact ? find(instrumentValue.factName) : -1
Component.onCompleted: currentIndex = instrumentValue.fact ? find(instrumentValue.factName) : -1
onActivated: {
_valueDialogInstrumentValue.setFact(_valueDialogInstrumentValue.factGroupName, currentText)
_valueDialogInstrumentValue.icon = ""
_valueDialogInstrumentValue.label = _valueDialogInstrumentValue.fact.shortDescription
instrumentValue.setFact(instrumentValue.factGroupName, currentText)
instrumentValue.icon = ""
instrumentValue.label = instrumentValue.fact.shortDescription
}
}
QGCRadioButton {
id: iconCheckBox
text: qsTr("Icon")
Component.onCompleted: checked = _valueDialogInstrumentValue.icon != ""
Component.onCompleted: checked = instrumentValue.icon != ""
onClicked: {
_valueDialogInstrumentValue.label = ""
_valueDialogInstrumentValue.icon = _valueDialogInstrumentValue.iconNames[0]
iconPickerDialogIcon = _valueDialogInstrumentValue.icon
iconPickerDialogUpdateIconFunction = function(icon){ _valueDialogInstrumentValue.icon = icon }
mainWindow.showPopupDialog(iconPickerDialog, qsTr("Select Icon"), StandardButton.Close)
instrumentValue.label = ""
instrumentValue.icon = instrumentValue.iconNames[0]
var updateFunction = function(icon){ instrumentValue.icon = icon }
mainWindow.showPopupDialog(iconPickerDialog, { iconNames: instrumentValue.iconNames, icon: instrumentValue.icon, updateIconFunction: updateFunction })
}
}
......@@ -357,7 +362,7 @@ Column {
Layout.alignment: Qt.AlignHCenter
height: iconPositionCombo.height
width: height
source: "/InstrumentValueIcons/" + (_valueDialogInstrumentValue.icon ? _valueDialogInstrumentValue.icon : _valueDialogInstrumentValue.iconNames[0])
source: "/InstrumentValueIcons/" + (instrumentValue.icon ? instrumentValue.icon : instrumentValue.iconNames[0])
sourceSize.height: height
fillMode: Image.PreserveAspectFit
mipmap: true
......@@ -368,29 +373,28 @@ Column {
MouseArea {
anchors.fill: parent
onClicked: {
iconPickerDialogIcon = _valueDialogInstrumentValue.icon
iconPickerDialogUpdateIconFunction = function(icon){ _valueDialogInstrumentValue.icon = icon }
mainWindow.showPopupDialog(iconPickerDialog, qsTr("Select Icon"), StandardButton.Close)
var updateFunction = function(icon){ instrumentValue.icon = icon }
mainWindow.showPopupDialog(iconPickerDialog, { iconNames: instrumentValue.iconNames, icon: instrumentValue.icon, updateIconFunction: updateFunction })
}
}
}
QGCComboBox {
id: iconPositionCombo
model: _valueDialogInstrumentValue.iconPositionNames
currentIndex: _valueDialogInstrumentValue.iconPosition
model: instrumentValue.iconPositionNames
currentIndex: instrumentValue.iconPosition
sizeToContents: true
onActivated: _valueDialogInstrumentValue.iconPosition = index
onActivated: instrumentValue.iconPosition = index
enabled: iconCheckBox.checked
}
QGCRadioButton {
id: labelCheckBox
text: qsTr("Label")
Component.onCompleted: checked = _valueDialogInstrumentValue.label != ""
Component.onCompleted: checked = instrumentValue.label != ""
onClicked: {
_valueDialogInstrumentValue.icon = ""
_valueDialogInstrumentValue.label = _valueDialogInstrumentValue.fact ? _valueDialogInstrumentValue.fact.shortDescription : qsTr("Label")
instrumentValue.icon = ""
instrumentValue.label = instrumentValue.fact ? instrumentValue.fact.shortDescription : qsTr("Label")
}
}
......@@ -398,7 +402,7 @@ Column {
id: labelTextField
Layout.fillWidth: true
Layout.columnSpan: 2
text: _valueDialogInstrumentValue.label
text: instrumentValue.label
enabled: labelCheckBox.checked
}
......@@ -406,16 +410,16 @@ Column {
QGCComboBox {
id: fontSizeCombo
model: _valueDialogInstrumentValue.fontSizeNames
currentIndex: _valueDialogInstrumentValue.fontSize
model: instrumentValue.fontSizeNames
currentIndex: instrumentValue.fontSize
sizeToContents: true
onActivated: _valueDialogInstrumentValue.fontSize = index
onActivated: instrumentValue.fontSize = index
}
QGCCheckBox {
text: qsTr("Show Units")
checked: _valueDialogInstrumentValue.showUnits
onClicked: _valueDialogInstrumentValue.showUnits = checked
checked: instrumentValue.showUnits
onClicked: instrumentValue.showUnits = checked
}
QGCLabel { text: qsTr("Range") }
......@@ -423,10 +427,10 @@ Column {
QGCComboBox {
id: rangeTypeCombo
Layout.columnSpan: 2
model: _valueDialogInstrumentValue.rangeTypeNames
currentIndex: _valueDialogInstrumentValue.rangeType
model: instrumentValue.rangeTypeNames
currentIndex: instrumentValue.rangeType
sizeToContents: true
onActivated: _valueDialogInstrumentValue.rangeType = index
onActivated: instrumentValue.rangeType = index
}
Loader {
......@@ -436,8 +440,10 @@ Column {
Layout.preferredWidth: item ? item.width : 0
Layout.preferredHeight: item ? item.height : 0
property var instrumentValue: valueDisplayDialog.instrumentValue
function updateSourceComponent() {
switch (_valueDialogInstrumentValue.rangeType) {
switch (instrumentValue.rangeType) {
case InstrumentValue.NoRangeInfo:
sourceComponent = undefined
break
......@@ -456,7 +462,7 @@ Column {
Component.onCompleted: updateSourceComponent()
Connections {
target: _valueDialogInstrumentValue
target: instrumentValue
onRangeTypeChanged: rangeLoader.updateSourceComponent()
}
......@@ -465,12 +471,16 @@ Column {
}
}
property string iconPickerDialogIcon
property var iconPickerDialogUpdateIconFunction
Component {
id: iconPickerDialog
QGCPopupDialog {
property var iconNames: dialogProperties.iconNames
property string icon: dialogProperties.icon
property var updateIconFunction: dialogProperties.updateIconFunction
title: qsTr("Select Icon")
buttons: StandardButton.Close
GridLayout {
columns: 10
......@@ -478,14 +488,14 @@ Column {
rowSpacing: 0
Repeater {
model: _valueDialogInstrumentValue.iconNames
model: iconNames
Rectangle {
height: ScreenTools.minTouchPixels
width: height
color: currentSelection ? qgcPal.text : qgcPal.window
property bool currentSelection: iconPickerDialogIcon == modelData
property bool currentSelection: icon == modelData
QGCColoredImage {
anchors.centerIn: parent
......@@ -501,8 +511,8 @@ Column {
MouseArea {
anchors.fill: parent
onClicked: {
iconPickerDialogIcon = modelData
iconPickerDialogUpdateIconFunction(modelData)
icon = modelData
updateIconFunction(modelData)
hideDialog()
}
}
......@@ -521,21 +531,21 @@ Column {
height: childrenRect.height
function updateRangeValue(index, text) {
var newValues = _valueDialogInstrumentValue.rangeValues
var newValues = instrumentValue.rangeValues
newValues[index] = parseFloat(text)
_valueDialogInstrumentValue.rangeValues = newValues
instrumentValue.rangeValues = newValues
}
function updateColorValue(index, color) {
var newColors = _valueDialogInstrumentValue.rangeColors
var newColors = instrumentValue.rangeColors
newColors[index] = color
_valueDialogInstrumentValue.rangeColors = newColors
instrumentValue.rangeColors = newColors
}
ColorDialog {
id: colorPickerDialog
modality: Qt.ApplicationModal
currentColor: _valueDialogInstrumentValue.rangeColors[colorIndex]
currentColor: instrumentValue.rangeColors[colorIndex]
onAccepted: updateColorValue(colorIndex, color)
property int colorIndex: 0
......@@ -560,13 +570,13 @@ Column {
spacing: _margins
Repeater {
model: _valueDialogInstrumentValue.rangeValues.length
model: instrumentValue.rangeValues.length
QGCButton {
width: ScreenTools.implicitTextFieldHeight
height: width
text: qsTr("-")
onClicked: _valueDialogInstrumentValue.removeRangeValue(index)
onClicked: instrumentValue.removeRangeValue(index)
}
}
}
......@@ -576,10 +586,10 @@ Column {
spacing: _margins
Repeater {
model: _valueDialogInstrumentValue.rangeValues.length
model: instrumentValue.rangeValues.length
QGCTextField {
text: _valueDialogInstrumentValue.rangeValues[index]
text: instrumentValue.rangeValues[index]
onEditingFinished: updateRangeValue(index, text)
}
}
......@@ -588,12 +598,12 @@ Column {
Column {
spacing: _margins
Repeater {
model: _valueDialogInstrumentValue.rangeColors
model: instrumentValue.rangeColors
QGCCheckBox {
height: ScreenTools.implicitTextFieldHeight
checked: _valueDialogInstrumentValue.isValidColor(_valueDialogInstrumentValue.rangeColors[index])
onClicked: updateColorValue(index, checked ? "green" : _valueDialogInstrumentValue.invalidColor())
checked: instrumentValue.isValidColor(instrumentValue.rangeColors[index])
onClicked: updateColorValue(index, checked ? "green" : instrumentValue.invalidColor())
}
}
}
......@@ -601,13 +611,13 @@ Column {
Column {
spacing: _margins
Repeater {
model: _valueDialogInstrumentValue.rangeColors
model: instrumentValue.rangeColors
Rectangle {
width: ScreenTools.implicitTextFieldHeight
height: width
border.color: qgcPal.text
color: _valueDialogInstrumentValue.isValidColor(modelData) ? modelData : qgcPal.text
color: instrumentValue.isValidColor(modelData) ? modelData : qgcPal.text
MouseArea {
anchors.fill: parent
......@@ -623,7 +633,7 @@ Column {
QGCButton {
text: qsTr("Add Row")
onClicked: _valueDialogInstrumentValue.addRangeValue()
onClicked: instrumentValue.addRangeValue()
}
}
}
......@@ -637,15 +647,15 @@ Column {
height: childrenRect.height
function updateRangeValue(index, text) {
var newValues = _valueDialogInstrumentValue.rangeValues
var newValues = instrumentValue.rangeValues
newValues[index] = parseFloat(text)
_valueDialogInstrumentValue.rangeValues = newValues
instrumentValue.rangeValues = newValues
}
function updateIconValue(index, icon) {
var newIcons = _valueDialogInstrumentValue.rangeIcons
var newIcons = instrumentValue.rangeIcons
newIcons[index] = icon
_valueDialogInstrumentValue.rangeIcons = newIcons
instrumentValue.rangeIcons = newIcons
}
Column {
......@@ -667,13 +677,13 @@ Column {
spacing: _margins
Repeater {
model: _valueDialogInstrumentValue.rangeValues.length
model: instrumentValue.rangeValues.length
QGCButton {
width: ScreenTools.implicitTextFieldHeight
height: width
text: qsTr("-")
onClicked: _valueDialogInstrumentValue.removeRangeValue(index)
onClicked: instrumentValue.removeRangeValue(index)
}
}
}
......@@ -683,10 +693,10 @@ Column {
spacing: _margins
Repeater {
model: _valueDialogInstrumentValue.rangeValues.length
model: instrumentValue.rangeValues.length
QGCTextField {
text: _valueDialogInstrumentValue.rangeValues[index]
text: instrumentValue.rangeValues[index]
onEditingFinished: updateRangeValue(index, text)
}
}
......@@ -696,7 +706,7 @@ Column {
spacing: _margins
Repeater {
model: _valueDialogInstrumentValue.rangeIcons
model: instrumentValue.rangeIcons
QGCColoredImage {
height: ScreenTools.implicitTextFieldHeight
......@@ -711,9 +721,8 @@ Column {
MouseArea {
anchors.fill: parent
onClicked: {
iconPickerDialogIcon = modelData
iconPickerDialogUpdateIconFunction = function(icon){ updateIconValue(index, icon) }
mainWindow.showPopupDialog(iconPickerDialog, qsTr("Select Icon"), StandardButton.Close)
var updateFunction = function(icon){ updateIconValue(index, icon) }
mainWindow.showPopupDialog(iconPickerDialog, { iconNames: instrumentValue.iconNames, icon: modelData, updateIconFunction = updateFunction })
}
}
}
......@@ -723,7 +732,7 @@ Column {
QGCButton {
text: qsTr("Add Row")
onClicked: _valueDialogInstrumentValue.addRangeValue()
onClicked: instrumentValue.addRangeValue()
}
}
}
......@@ -737,15 +746,15 @@ Column {
height: childrenRect.height
function updateRangeValue(index, text) {
var newValues = _valueDialogInstrumentValue.rangeValues
var newValues = instrumentValue.rangeValues
newValues[index] = parseFloat(text)
_valueDialogInstrumentValue.rangeValues = newValues
instrumentValue.rangeValues = newValues
}
function updateOpacityValue(index, opacity) {
var newOpacities = _valueDialogInstrumentValue.rangeOpacities
var newOpacities = instrumentValue.rangeOpacities
newOpacities[index] = opacity
_valueDialogInstrumentValue.rangeOpacities = newOpacities
instrumentValue.rangeOpacities = newOpacities
}
Column {
......@@ -767,13 +776,13 @@ Column {
spacing: _margins
Repeater {
model: _valueDialogInstrumentValue.rangeValues.length
model: instrumentValue.rangeValues.length
QGCButton {
width: ScreenTools.implicitTextFieldHeight
height: width
text: qsTr("-")
onClicked: _valueDialogInstrumentValue.removeRangeValue(index)
onClicked: instrumentValue.removeRangeValue(index)
}
}
}
......@@ -783,7 +792,7 @@ Column {
spacing: _margins
Repeater {
model: _valueDialogInstrumentValue.rangeValues
model: instrumentValue.rangeValues
QGCTextField {
text: modelData
......@@ -796,7 +805,7 @@ Column {
spacing: _margins
Repeater {
model: _valueDialogInstrumentValue.rangeOpacities
model: instrumentValue.rangeOpacities
QGCTextField {
text: modelData
......@@ -808,7 +817,7 @@ Column {
QGCButton {
text: qsTr("Add Row")
onClicked: _valueDialogInstrumentValue.addRangeValue()
onClicked: instrumentValue.addRangeValue()
}
}
}
......
......@@ -101,6 +101,7 @@
#include "VehicleObjectAvoidance.h"
#include "TrajectoryPoints.h"
#include "ValuesWidgetController.h"
#include "RCToParamDialogController.h"
#if defined(QGC_ENABLE_PAIRING)
#include "PairingManager.h"
......@@ -540,6 +541,7 @@ void QGCApplication::_initCommon()
qmlRegisterType<LogDownloadController> (kQGCControllers, 1, 0, "LogDownloadController");
qmlRegisterType<SyslinkComponentController> (kQGCControllers, 1, 0, "SyslinkComponentController");
qmlRegisterType<EditPositionDialogController> (kQGCControllers, 1, 0, "EditPositionDialogController");
qmlRegisterType<RCToParamDialogController> (kQGCControllers, 1, 0, "RCToParamDialogController");
#ifndef __mobile__
#ifndef NO_SERIAL_LINK
......
......@@ -28,7 +28,8 @@ Item {
property int _rowWidth: 10 // Dynamic adjusted at runtime
property bool _searchFilter: searchText.text.trim() != "" ///< true: showing results of search
property var _searchResults ///< List of parameter names from search results
property bool _showRCToParam: !ScreenTools.isMobile && QGroundControl.multiVehicleManager.activeVehicle.px4Firmware
property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
property bool _showRCToParam: _activeVehicle.px4Firmware
property var _appSettings: QGroundControl.settingsManager.appSettings
ParameterEditorController {
......@@ -133,8 +134,8 @@ Item {
}
QGCMenuSeparator { visible: _showRCToParam }
QGCMenuItem {
text: qsTr("Clear RC to Param")
onTriggered: controller.clearRCToParam()
text: qsTr("Clear all RC to Param")
onTriggered: _activeVehicle.clearAllParamMapRC()
visible: _showRCToParam
}
QGCMenuSeparator { }
......
......@@ -86,13 +86,6 @@ QStringList ParameterEditorController::searchParameters(const QString& searchTex
return list;
}
void ParameterEditorController::clearRCToParam(void)
{
if (_uas) {
_uas->unsetRCToParameterMap();
}
}
void ParameterEditorController::saveToFile(const QString& filename)
{
if (!filename.isEmpty()) {
......
......@@ -41,7 +41,6 @@ public:
Q_INVOKABLE QStringList getGroupsForCategory(const QString& category);
Q_INVOKABLE QStringList searchParameters(const QString& searchText, bool searchInName=true, bool searchInDescriptions=true);
Q_INVOKABLE void clearRCToParam(void);
Q_INVOKABLE void saveToFile(const QString& filename);
Q_INVOKABLE void loadFromFile(const QString& filename);
Q_INVOKABLE void refresh(void);
......
......@@ -10,6 +10,7 @@
import QtQuick 2.3
import QtQuick.Controls 1.2
import QtQuick.Layouts 1.2
import QtQuick.Dialogs 1.3
import QGroundControl 1.0
import QGroundControl.Controls 1.0
......@@ -125,8 +126,8 @@ QGCViewDialog {
Layout.fillWidth: true
focus: setFocus
inputMethodHints: (fact.typeIsString || ScreenTools.isiOS) ?
Qt.ImhNone : // iOS numeric keyboard has no done button, we can't use it
Qt.ImhFormattedNumbersOnly // Forces use of virtual numeric keyboard
Qt.ImhNone : // iOS numeric keyboard has no done button, we can't use it
Qt.ImhFormattedNumbersOnly // Forces use of virtual numeric keyboard
}
QGCButton {
......@@ -286,11 +287,19 @@ QGCViewDialog {
}
QGCButton {
text: qsTr("Set RC to Param...")
width: _editFieldWidth
visible: _advanced.checked && !validate && showRCToParam
onClicked: controller.setRCToParam(fact.name)
text: qsTr("Set RC to Param")
width: _editFieldWidth
visible: _advanced.checked && !validate && showRCToParam
onClicked: mainWindow.showPopupDialog(rcToParamDialog)
}
} // Column
}
Component {
id: rcToParamDialog
RCToParamDialog {
tuningFact: fact
}
}
} // QGCViewDialog
......@@ -7,9 +7,13 @@
*
****************************************************************************/
import QtQuick 2.12
import QtQuick 2.12
import QtQuick.Dialogs 1.3
Item {
property string title
property var buttons: StandardButton.Ok
width: childrenRect.width
height: childrenRect.height
......
......@@ -18,7 +18,10 @@ import QGroundControl.Palette 1.0
import QGroundControl.ScreenTools 1.0
Popup {
id: root
property var dialogComponent
property var dialogProperties
id: popupRoot
anchors.centerIn: parent
width: mainFlickable.width + (padding * 2)
height: mainFlickable.height + (padding * 2)
......@@ -26,68 +29,66 @@ Popup {
modal: true
focus: true
property var pal: QGroundControl.globalPalette
property real frameSize: ScreenTools.defaultFontPixelWidth
property var _pal: QGroundControl.globalPalette
property real _frameSize: ScreenTools.defaultFontPixelWidth
property string _dialogTitle
property real _contentMargin: ScreenTools.defaultFontPixelHeight / 2
property real _popupDoubleInset: ScreenTools.defaultFontPixelHeight * 2
property real _maxAvailableWidth: parent.width - _popupDoubleInset
property real _maxAvailableHeight: parent.height - _popupDoubleInset
background: Item {
Rectangle {
anchors.left: parent.left
anchors.top: parent.top
width: frameSize
height: frameSize
color: pal.text
width: _frameSize
height: _frameSize
color: _pal.text
visible: enabled
}
Rectangle {
anchors.right: parent.right
anchors.top: parent.top
width: frameSize
height: frameSize
color: pal.text
width: _frameSize
height: _frameSize
color: _pal.text
visible: enabled
}
Rectangle {
anchors.left: parent.left
anchors.bottom: parent.bottom
width: frameSize
height: frameSize
color: pal.text
width: _frameSize
height: _frameSize
color: _pal.text
visible: enabled
}
Rectangle {
anchors.right: parent.right
anchors.bottom: parent.bottom
width: frameSize
height: frameSize
color: pal.text
width: _frameSize
height: _frameSize
color: _pal.text
visible: enabled
}
Rectangle {
anchors.margins: root.padding
anchors.margins: popupRoot.padding
anchors.fill: parent
color: pal.window
color: _pal.window
}
}
property string title
property var buttons
property var dialogComponent
property real _contentMargin: ScreenTools.defaultFontPixelHeight / 2
property real _popupDoubleInset: ScreenTools.defaultFontPixelHeight * 2
property real _maxAvailableWidth: parent.width - _popupDoubleInset
property real _maxAvailableHeight: parent.height - _popupDoubleInset
Component.onCompleted: setupDialogButtons()
Component.onCompleted: {
_dialogTitle = dialogComponentLoader.item.title
setupDialogButtons(dialogComponentLoader.item.buttons)
}
QGCPalette { id: qgcPal; colorGroupEnabled: parent.enabled }
function setupDialogButtons() {
function setupDialogButtons(buttons) {
acceptButton.visible = false
rejectButton.visible = false
// Accept role buttons
......@@ -210,8 +211,10 @@ Popup {
x: _contentMargin
sourceComponent: dialogComponent
focus: true
property bool acceptAllowed: acceptButton.visible
property bool rejectAllowed: rejectButton.visible
property var dialogProperties: popupRoot.dialogProperties
property bool acceptAllowed: acceptButton.visible
property bool rejectAllowed: rejectButton.visible
}
}
}
......
......@@ -80,6 +80,7 @@ RallyPointEditorHeader 1.0 RallyPointEditorHeader.qml
RallyPointItemEditor 1.0 RallyPointItemEditor.qml
RallyPointMapVisuals 1.0 RallyPointMapVisuals.qml
RCChannelMonitor 1.0 RCChannelMonitor.qml
RCToParamDialog 1.0 RCToParamDialog.qml
RoundButton 1.0 RoundButton.qml
SectionHeader 1.0 SectionHeader.qml
SetupPage 1.0 SetupPage.qml
......
[
{
"name": "Scale",
"shortDescription": "Scale the RC range",
"type": "double",
"min": -1,
"max": 1,
"defaultValue": 1,
"decimalPlaces": 1
},
{
"name": "CenterValue",
"shortDescription": "Parameter value when RC output is 0",
"type": "double",
"min": -180.0,
"max": 180.0,
"decimalPlaces": 7
},
{
"name": "MinValue",
"shortDescription": "Minimum parameter value",
"type": "double",
"decimalPlaces": 7
},
{
"name": "MaxValue",
"shortDescription": "Maximum parameter value",
"type": "double",
"decimalPlaces": 7
}
]
/****************************************************************************
*
* (c) 2009-2020 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.
*
****************************************************************************/
import QtQuick 2.12
import QtQuick.Layouts 1.2
import QtQuick.Controls 2.5
import QtQuick.Dialogs 1.3
import QGroundControl 1.0
import QGroundControl.Controls 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.FactSystem 1.0
import QGroundControl.FactControls 1.0
import QGroundControl.Controllers 1.0
QGCPopupDialog {
property alias tuningFact: controller.tuningFact
title: qsTr("RC To Param")
buttons: StandardButton.Cancel | StandardButton.Ok
function accept() {
QGroundControl.multiVehicleManager.activeVehicle.sendParamMapRC(tuningFact.name, scale.text, centerValue.text, tuningID.currentIndex, minValue.text, maxValue.text);
hideDialog()
}
RCToParamDialogController {
id: controller
}
ColumnLayout {
spacing: ScreenTools.defaultDialogControlSpacing
QGCLabel {
Layout.preferredWidth: mainGrid.width
Layout.fillWidth: true
wrapMode: Text.WordWrap
text: qsTr("Bind an RC Channel to a parameter value. Tuning IDs can be mapped to an RC Channel from Radio Setup page.")
}
QGCLabel {
Layout.preferredWidth: mainGrid.width
Layout.fillWidth: true
text: qsTr("Waiting on parameter update from Vehicle.")
visible: !controller.ready
}
GridLayout {
id: mainGrid
columns: 2
rowSpacing: ScreenTools.defaultDialogControlSpacing
columnSpacing: ScreenTools.defaultDialogControlSpacing
enabled: controller.ready
QGCLabel { text: qsTr("Parameter") }
QGCLabel { text: tuningFact.name }
QGCLabel { text: qsTr("Tuning ID") }
QGCComboBox {
id: tuningID
Layout.fillWidth: true
currentIndex: 0
model: [ 1, 2, 3 ]
}
QGCLabel { text: qsTr("Scale") }
QGCTextField {
id: scale
text: controller.scale.valueString
}
QGCLabel { text: qsTr("Center Value") }
QGCTextField {
id: centerValue
text: controller.center.valueString
}
QGCLabel { text: qsTr("Min Value") }
QGCTextField {
id: minValue
text: controller.min.valueString
}
QGCLabel { text: qsTr("Max Value") }
QGCTextField {
id: maxValue
text: controller.max.valueString
}
}
QGCLabel {
Layout.preferredWidth: mainGrid.width
Layout.fillWidth: true
wrapMode: Text.WordWrap
text: qsTr("Double check that all values are correct prior to confirming dialog.")
}
}
}
/****************************************************************************
*
* (c) 2009-2020 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.
*
****************************************************************************/
#include "RCToParamDialogController.h"
#include "QGCApplication.h"
#include "ParameterManager.h"
const char* RCToParamDialogController::_scaleFactName = "Scale";
const char* RCToParamDialogController::_centerFactName = "CenterValue";
const char* RCToParamDialogController::_minFactName = "MinValue";
const char* RCToParamDialogController::_maxFactName = "MaxValue";
QMap<QString, FactMetaData*> RCToParamDialogController::_metaDataMap;
RCToParamDialogController::RCToParamDialogController(void)
: _scaleFact (0, _scaleFactName, FactMetaData::valueTypeDouble)
, _centerFact (0, _centerFactName, FactMetaData::valueTypeDouble)
, _minFact (0, _minFactName, FactMetaData::valueTypeDouble)
, _maxFact (0, _maxFactName, FactMetaData::valueTypeDouble)
{
if (_metaDataMap.isEmpty()) {
_metaDataMap = FactMetaData::createMapFromJsonFile(QStringLiteral(":/json/RCToParamDialog.FactMetaData.json"), nullptr /* QObject parent */);
}
_scaleFact.setMetaData (_metaDataMap[_scaleFactName], true /* setDefaultFromMetaData */);
_centerFact.setMetaData (_metaDataMap[_centerFactName]);
_minFact.setMetaData (_metaDataMap[_minFactName]);
_maxFact.setMetaData (_metaDataMap[_maxFactName]);
}
void RCToParamDialogController::setTuningFact(Fact* tuningFact)
{
_tuningFact = tuningFact;
emit tuningFactChanged(tuningFact);
_centerFact.setRawValue(_tuningFact->rawValue().toDouble());
_minFact.setRawValue(_tuningFact->rawMin().toDouble());
_maxFact.setRawValue(_tuningFact->rawMax().toDouble());
connect(_tuningFact, &Fact::vehicleUpdated, this, &RCToParamDialogController::_parameterUpdated);
qgcApp()->toolbox()->multiVehicleManager()->activeVehicle()->parameterManager()->refreshParameter(FactSystem::defaultComponentId, _tuningFact->name());
}
void RCToParamDialogController::_parameterUpdated(void)
{
_ready = true;
emit readyChanged(true);
}
/****************************************************************************
*
* (c) 2009-2020 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.
*
****************************************************************************/
#pragma once
#include <QObject>
#include <QGeoCoordinate>
#include "FactSystem.h"
class RCToParamDialogController : public QObject
{
Q_OBJECT
public:
RCToParamDialogController(void);
Q_PROPERTY(Fact* tuningFact READ tuningFact WRITE setTuningFact NOTIFY tuningFactChanged)
Q_PROPERTY(bool ready MEMBER _ready NOTIFY readyChanged) // true: editing can begin, false: still waiting for param update from vehicle
Q_PROPERTY(Fact* scale READ scale CONSTANT)
Q_PROPERTY(Fact* center READ center CONSTANT)
Q_PROPERTY(Fact* min READ min CONSTANT)
Q_PROPERTY(Fact* max READ max CONSTANT)
Fact* tuningFact (void) { return _tuningFact; }
Fact* scale (void) { return &_scaleFact; }
Fact* center (void) { return &_centerFact; }
Fact* min (void) { return &_minFact; }
Fact* max (void) { return &_maxFact; }
void setTuningFact (Fact* tuningFact);
signals:
void tuningFactChanged (Fact* fact);
void readyChanged (bool ready);
private slots:
void _parameterUpdated(void);
private:
static QMap<QString, FactMetaData*> _metaDataMap;
Fact* _tuningFact = nullptr;
bool _ready = false;
Fact _scaleFact;
Fact _centerFact;
Fact _minFact;
Fact _maxFact;
static const char* _scaleFactName;
static const char* _centerFactName;
static const char* _minFactName;
static const char* _maxFactName;
};
......@@ -46,6 +46,9 @@ Item {
/// QFontMetrics::descent for default font at default point size
property real defaultFontDescent: 0
/// The default amount of space in between controls in a dialog
property real defaultDialogControlSpacing: defaultFontPixelHeight / 2
property real smallFontPointSize: 10
property real mediumFontPointSize: 10
property real largeFontPointSize: 10
......
......@@ -4337,6 +4337,54 @@ void Vehicle::updateFlightDistance(double distance)
_flightDistanceFact.setRawValue(_flightDistanceFact.rawValue().toDouble() + distance);
}
void Vehicle::sendParamMapRC(const QString& paramName, double scale, double centerValue, int tuningID, double minValue, double maxValue)
{
mavlink_message_t message;
char param_id_cstr[MAVLINK_MSG_PARAM_MAP_RC_FIELD_PARAM_ID_LEN] = {};
// Copy string into buffer, ensuring not to exceed the buffer size
for (unsigned int i = 0; i < sizeof(param_id_cstr); i++) {
if ((int)i < paramName.length()) {
param_id_cstr[i] = paramName.toLatin1()[i];
}
}
mavlink_msg_param_map_rc_pack_chan(static_cast<uint8_t>(_mavlink->getSystemId()),
static_cast<uint8_t>(_mavlink->getComponentId()),
priorityLink()->mavlinkChannel(),
&message,
_id,
MAV_COMP_ID_AUTOPILOT1,
param_id_cstr,
-1, // parameter name specified as string in previous argument
static_cast<uint8_t>(tuningID),
static_cast<float>(scale),
static_cast<float>(centerValue),
static_cast<float>(minValue),
static_cast<float>(maxValue));
sendMessageOnLink(priorityLink(), message);
}
void Vehicle::clearAllParamMapRC(void)
{
char param_id_cstr[MAVLINK_MSG_PARAM_MAP_RC_FIELD_PARAM_ID_LEN] = {};
for (int i = 0; i < 3; i++) {
mavlink_message_t message;
mavlink_msg_param_map_rc_pack_chan(static_cast<uint8_t>(_mavlink->getSystemId()),
static_cast<uint8_t>(_mavlink->getComponentId()),
priorityLink()->mavlinkChannel(),
&message,
_id,
MAV_COMP_ID_AUTOPILOT1,
param_id_cstr,
-2, // Disable map for specified tuning id
i, // tuning id
0, 0, 0, 0); // unused
sendMessageOnLink(priorityLink(), message);
}
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
......
......@@ -781,6 +781,13 @@ public:
Q_INVOKABLE void gimbalYawStep (int direction);
Q_INVOKABLE void centerGimbal ();
/// Sends PARAM_MAP_RC message to vehicle
Q_INVOKABLE void sendParamMapRC(const QString& paramName, double scale, double centerValue, int tuningID, double minValue, double maxValue);
/// Clears all PARAM_MAP_RC settings from vehicle
Q_INVOKABLE void clearAllParamMapRC(void);
#if !defined(NO_ARDUPILOT_DIALECT)
Q_INVOKABLE void flashBootloader();
#endif
......
......@@ -505,6 +505,10 @@ void MockLink::_handleIncomingMavlinkBytes(const uint8_t* bytes, int cBytes)
_handleLogRequestData(msg);
break;
case MAVLINK_MSG_ID_PARAM_MAP_RC:
_handleParamMapRC(msg);
break;
default:
break;
}
......@@ -517,6 +521,22 @@ void MockLink::_handleHeartBeat(const mavlink_message_t& msg)
qCDebug(MockLinkLog) << "Heartbeat";
}
void MockLink::_handleParamMapRC(const mavlink_message_t& msg)
{
mavlink_param_map_rc_t paramMapRC;
mavlink_msg_param_map_rc_decode(&msg, &paramMapRC);
const QString paramName(QString::fromLocal8Bit(paramMapRC.param_id, static_cast<int>(strnlen(paramMapRC.param_id, MAVLINK_MSG_PARAM_MAP_RC_FIELD_PARAM_ID_LEN))));
if (paramMapRC.param_index == -1) {
qDebug() << QStringLiteral("MockLink - PARAM_MAP_RC: param(%1) tuningID(%2) centerValue(%3) scale(%4) min(%5) max(%6)").arg(paramName).arg(paramMapRC.parameter_rc_channel_index).arg(paramMapRC.param_value0).arg(paramMapRC.scale).arg(paramMapRC.param_value_min).arg(paramMapRC.param_value_max);
} else if (paramMapRC.param_index == -2) {
qDebug() << QStringLiteral("MockLink - PARAM_MAP_RC: Clear tuningID(%1)").arg(paramMapRC.parameter_rc_channel_index);
} else {
qWarning() << QStringLiteral("MockLink - PARAM_MAP_RC: Unsupported param_index(%1)").arg(paramMapRC.param_index);
}
}
void MockLink::_handleSetMode(const mavlink_message_t& msg)
{
mavlink_set_mode_t request;
......
......@@ -192,6 +192,7 @@ private:
void _handlePreFlightCalibration (const mavlink_command_long_t& request);
void _handleLogRequestList (const mavlink_message_t& msg);
void _handleLogRequestData (const mavlink_message_t& msg);
void _handleParamMapRC (const mavlink_message_t& msg);
float _floatUnionForParam (int componentId, const QString& paramName);
void _setParamFloatUnionIntoMap (int componentId, const QString& paramName, float paramFloat);
void _sendHomePosition (void);
......
......@@ -986,68 +986,6 @@ void UAS::pairRX(int rxType, int rxSubType)
}
}
void UAS::sendMapRCToParam(QString param_id, float scale, float value0, quint8 param_rc_channel_index, float valueMin, float valueMax)
{
if (!_vehicle) {
return;
}
mavlink_message_t message;
char param_id_cstr[MAVLINK_MSG_PARAM_MAP_RC_FIELD_PARAM_ID_LEN] = {};
// Copy string into buffer, ensuring not to exceed the buffer size
for (unsigned int i = 0; i < sizeof(param_id_cstr); i++)
{
if ((int)i < param_id.length())
{
param_id_cstr[i] = param_id.toLatin1()[i];
}
}
mavlink_msg_param_map_rc_pack_chan(mavlink->getSystemId(),
mavlink->getComponentId(),
_vehicle->priorityLink()->mavlinkChannel(),
&message,
this->uasId,
_vehicle->defaultComponentId(),
param_id_cstr,
-1,
param_rc_channel_index,
value0,
scale,
valueMin,
valueMax);
_vehicle->sendMessageOnLink(_vehicle->priorityLink(), message);
//qDebug() << "Mavlink message sent";
}
void UAS::unsetRCToParameterMap()
{
if (!_vehicle) {
return;
}
char param_id_cstr[MAVLINK_MSG_PARAM_MAP_RC_FIELD_PARAM_ID_LEN] = {};
for (int i = 0; i < 3; i++) {
mavlink_message_t message;
mavlink_msg_param_map_rc_pack_chan(mavlink->getSystemId(),
mavlink->getComponentId(),
_vehicle->priorityLink()->mavlinkChannel(),
&message,
this->uasId,
_vehicle->defaultComponentId(),
param_id_cstr,
-2,
i,
0.0f,
0.0f,
0.0f,
0.0f);
_vehicle->sendMessageOnLink(_vehicle->priorityLink(), message);
}
}
void UAS::shutdownVehicle(void)
{
_vehicle = nullptr;
......
......@@ -210,11 +210,6 @@ public slots:
void startBusConfig(StartBusConfigType calType);
void stopBusConfig(void);
/** @brief Send command to map a RC channel to a parameter */
void sendMapRCToParam(QString param_id, float scale, float value0, quint8 param_rc_channel_index, float valueMin, float valueMax);
/** @brief Send command to disable all bindings/maps between RC and parameters */
void unsetRCToParameterMap();
signals:
void imageStarted(quint64 timestamp);
/** @brief A new camera image has arrived */
......
......@@ -82,12 +82,6 @@ public slots:
/** @brief Order the robot to pair its receiver **/
virtual void pairRX(int rxType, int rxSubType) = 0;
/** @brief Send command to map a RC channel to a parameter */
virtual void sendMapRCToParam(QString param_id, float scale, float value0, quint8 param_rc_channel_index, float valueMin, float valueMax) = 0;
/** @brief Send command to disable all bindings/maps between RC and parameters */
virtual void unsetRCToParameterMap() = 0;
signals:
/** @brief The robot is connected **/
void connected();
......
......@@ -229,13 +229,13 @@ ApplicationWindow {
}
}
function showPopupDialog(component, title, buttons) {
var popup = popupDialogContainterComponent.createObject(mainWindow, { "title": title, "buttons": buttons, "dialogComponent": component})
popup.open()
function showPopupDialog(component, properties) {
var dialog = popupDialogContainerComponent.createObject(mainWindow, { dialogComponent: component, dialogProperties: properties })
dialog.open()
}
Component {
id: popupDialogContainterComponent
id: popupDialogContainerComponent
QGCPopupDialogContainer { }
}
......
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