地面站终端 App
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

642 lines
25 KiB

/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Dialogs 1.2
import QGroundControl.Palette 1.0
import QGroundControl.Controls 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.Controllers 1.0
import QGroundControl.FactSystem 1.0
/// Joystick Config
QGCView {
id: rootQGCView
viewPanel: panel
QGCPalette { id: qgcPal; colorGroupEnabled: panel.enabled }
readonly property string dialogTitle: "Joystick Config"
readonly property real labelToMonitorMargin: defaultTextWidth * 3
property bool controllerCompleted: false
property bool controllerAndViewReady: false
property var _activeVehicle: multiVehicleManager.activeVehicle
property var _activeJoystick: joystickManager.activeJoystick
JoystickConfigController {
id: controller
factPanel: panel
statusText: statusText
cancelButton: cancelButton
nextButton: nextButton
skipButton: skipButton
Component.onCompleted: {
controllerCompleted = true
if (rootQGCView.completedSignalled) {
controllerAndViewReady = true
controller.start()
}
}
}
onCompleted: {
if (controllerCompleted) {
controllerAndViewReady = true
controller.start()
updateAxisCount()
}
}
QGCViewPanel {
id: panel
anchors.fill: parent
// Live axis monitor control component
Component {
id: axisMonitorDisplayComponent
Item {
property int axisValue: 0
property int __lastAxisValue: 0
readonly property int __axisValueMaxJitter: 100
property color __barColor: qgcPal.windowShade
// Bar
Rectangle {
id: bar
anchors.verticalCenter: parent.verticalCenter
width: parent.width
height: parent.height / 2
color: __barColor
}
// Center point
Rectangle {
anchors.horizontalCenter: parent.horizontalCenter
width: defaultTextWidth / 2
height: parent.height
color: qgcPal.window
}
// Indicator
Rectangle {
anchors.verticalCenter: parent.verticalCenter
width: parent.height * 0.75
height: width
x: (reversed ? (parent.width - _indicatorPosition) : _indicatorPosition) - (width / 2)
radius: width / 2
color: qgcPal.text
visible: mapped
property real _percentAxisValue: ((axisValue + 32768.0) / (32768.0 * 2))
property real _indicatorPosition: parent.width * _percentAxisValue
}
QGCLabel {
anchors.fill: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: "Not Mapped"
visible: !mapped
}
ColorAnimation {
id: barAnimation
target: bar
property: "color"
from: "yellow"
to: __barColor
duration: 1500
}
/*
// Axis value debugger
QGCLabel {
anchors.fill: parent
text: axisValue
}
*/
}
} // Component - axisMonitorDisplayComponent
// Main view Qml starts here
QGCLabel {
id: header
font.pixelSize: ScreenTools.mediumFontPixelSize
text: "JOYSTICK"
}
Item {
id: spacer
anchors.top: header.bottom
width: parent.width
height: 10
}
// Left side column
Column {
id: leftColumn
anchors.rightMargin: ScreenTools.defaultFontPixelWidth
anchors.top: spacer.bottom
anchors.left: parent.left
anchors.right: rightColumn.left
spacing: 10
// Attitude Controls
Column {
width: parent.width
spacing: 5
QGCLabel { text: "Attitude Controls" }
Item {
width: parent.width
height: defaultTextHeight * 2
QGCLabel {
id: rollLabel
width: defaultTextWidth * 10
text: "Roll"
}
Loader {
id: rollLoader
anchors.left: rollLabel.right
anchors.right: parent.right
height: rootQGCView.defaultTextHeight
width: 100
sourceComponent: axisMonitorDisplayComponent
property real defaultTextWidth: rootQGCView.defaultTextWidth
property bool mapped: controller.rollAxisMapped
property bool reversed: controller.rollAxisReversed
}
Connections {
target: controller
onRollAxisValueChanged: rollLoader.item.axisValue = value
}
}
Item {
width: parent.width
height: defaultTextHeight * 2
QGCLabel {
id: pitchLabel
width: defaultTextWidth * 10
text: "Pitch"
}
Loader {
id: pitchLoader
anchors.left: pitchLabel.right
anchors.right: parent.right
height: rootQGCView.defaultTextHeight
width: 100
sourceComponent: axisMonitorDisplayComponent
property real defaultTextWidth: rootQGCView.defaultTextWidth
property bool mapped: controller.pitchAxisMapped
property bool reversed: controller.pitchAxisReversed
}
Connections {
target: controller
onPitchAxisValueChanged: pitchLoader.item.axisValue = value
}
}
Item {
width: parent.width
height: defaultTextHeight * 2
QGCLabel {
id: yawLabel
width: defaultTextWidth * 10
text: "Yaw"
}
Loader {
id: yawLoader
anchors.left: yawLabel.right
anchors.right: parent.right
height: rootQGCView.defaultTextHeight
width: 100
sourceComponent: axisMonitorDisplayComponent
property real defaultTextWidth: rootQGCView.defaultTextWidth
property bool mapped: controller.yawAxisMapped
property bool reversed: controller.yawAxisReversed
}
Connections {
target: controller
onYawAxisValueChanged: yawLoader.item.axisValue = value
}
}
Item {
width: parent.width
height: defaultTextHeight * 2
QGCLabel {
id: throttleLabel
width: defaultTextWidth * 10
text: "Throttle"
}
Loader {
id: throttleLoader
anchors.left: throttleLabel.right
anchors.right: parent.right
height: rootQGCView.defaultTextHeight
width: 100
sourceComponent: axisMonitorDisplayComponent
property real defaultTextWidth: rootQGCView.defaultTextWidth
property bool mapped: controller.throttleAxisMapped
property bool reversed: controller.throttleAxisReversed
}
Connections {
target: controller
onThrottleAxisValueChanged: throttleLoader.item.axisValue = value
}
}
} // Column - Attitude Control labels
// Command Buttons
Row {
spacing: 10
QGCButton {
id: skipButton
text: "Skip"
onClicked: controller.skipButtonClicked()
}
QGCButton {
id: cancelButton
text: "Cancel"
onClicked: controller.cancelButtonClicked()
}
QGCButton {
id: nextButton
primary: true
text: "Calibrate"
onClicked: controller.nextButtonClicked()
}
} // Row - Buttons
// Status Text
QGCLabel {
id: statusText
width: parent.width
wrapMode: Text.WordWrap
}
Rectangle {
width: parent.width
height: 1
border.color: qgcPal.text
border.width: 1
}
// Settings
Row {
width: parent.width
spacing: ScreenTools.defaultFontPixelWidth
// Left column settings
Column {
width: parent.width / 2
spacing: ScreenTools.defaultFontPixelHeight
QGCLabel { text: "Additional Joystick settings:" }
Column {
width: parent.width
spacing: ScreenTools.defaultFontPixelHeight
QGCCheckBox {
enabled: allowEnableDisable
text: _activeJoystick.calibrated ? (rcInMode.value < 2 ? "Enable joystick input, disable RC input" : "Enable/Disable not allowed (COM_RC_IN_MODE=2)") : "Enable/Disable not allowed (Calibrate First)"
checked: _activeVehicle.joystickEnabled
property bool allowEnableDisable: _activeJoystick.calibrated && rcInMode.value < 2
property Fact rcInMode: controller.getParameterFact(-1, "COM_RC_IN_MODE")
onClicked: _activeVehicle.joystickEnabled = checked
}
Row {
width: parent.width
spacing: ScreenTools.defaultFontPixelWidth
QGCLabel {
id: activeJoystickLabel
anchors.baseline: joystickCombo.baseline
text: "Active joystick:"
}
QGCComboBox {
id: joystickCombo
width: parent.width - activeJoystickLabel.width - parent.spacing
model: joystickManager.joystickNames
onActivated: joystickManager.activeJoystickName = textAt(index)
Component.onCompleted: {
var index = joystickCombo.find(joystickManager.activeJoystickName)
if (index == -1) {
console.warn("Active joystick name not in combo", joystickManager.activeJoystickName)
} else {
joystickCombo.currentIndex = index
}
}
}
}
Column {
spacing: ScreenTools.defaultFontPixelHeight / 3
ExclusiveGroup { id: throttleModeExclusiveGroup }
QGCRadioButton {
exclusiveGroup: throttleModeExclusiveGroup
text: "Center stick is zero throttle"
checked: _activeJoystick.throttleMode == 0
onClicked: _activeJoystick.throttleMode = 0
}
QGCRadioButton {
exclusiveGroup: throttleModeExclusiveGroup
text: "Full down stick is zero throttle"
checked: _activeJoystick.throttleMode == 1
onClicked: _activeJoystick.throttleMode = 1
}
}
QGCCheckBox {
id: advancedSettings
checked: _activeVehicle.joystickMode != 0
text: "Advanced settings (careful!)"
onClicked: {
if (!checked) {
_activeVehicle.joystickMode = 0
}
}
}
Row {
width: parent.width
spacing: ScreenTools.defaultFontPixelWidth
visible: advancedSettings.checked
QGCLabel {
id: joystickModeLabel
anchors.baseline: joystickModeCombo.baseline
text: "Joystick mode:"
}
QGCComboBox {
id: joystickModeCombo
currentIndex: _activeVehicle.joystickMode
width: ScreenTools.defaultFontPixelWidth * 20
model: _activeVehicle.joystickModes
onActivated: _activeVehicle.joystickMode = index
}
}
}
} // Column - left column
// Right column settings
Column {
width: parent.width / 2
spacing: ScreenTools.defaultFontPixelHeight
Connections {
target: _activeJoystick
onRawButtonPressedChanged: {
if (buttonActionRepeater.itemAt(index)) {
buttonActionRepeater.itemAt(index).pressed = pressed
}
}
}
QGCLabel { text: "Button actions:" }
Column {
width: parent.width
spacing: ScreenTools.defaultFontPixelHeight / 3
QGCLabel {
visible: _activeVehicle.manualControlReservedButtonCount != 0
text: "Buttons 0-" + reservedButtonCount + " reserved for firmware use"
property int reservedButtonCount: _activeVehicle.manualControlReservedButtonCount == -1 ? _activeJoystick.buttonCount : _activeVehicle.manualControlReservedButtonCount
}
Repeater {
id: buttonActionRepeater
model: _activeJoystick.buttonCount
Row {
spacing: ScreenTools.defaultFontPixelWidth
visible: _activeVehicle.manualControlReservedButtonCount == -1 ? false : modelData >= _activeVehicle.manualControlReservedButtonCount
property bool pressed
QGCCheckBox {
anchors.verticalCenter: parent.verticalCenter
checked: _activeJoystick.buttonActions[modelData] != ""
onClicked: _activeJoystick.setButtonAction(modelData, checked ? buttonActionCombo.textAt(buttonActionCombo.currentIndex) : "")
}
Rectangle {
anchors.verticalCenter: parent.verticalCenter
width: ScreenTools.defaultFontPixelHeight * 1.5
height: width
border.width: 1
border.color: qgcPal.text
color: pressed ? qgcPal.buttonHighlight : qgcPal.button
QGCLabel {
anchors.fill: parent
color: pressed ? qgcPal.buttonHighlightText : qgcPal.buttonText
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: modelData
}
}
QGCComboBox {
id: buttonActionCombo
width: ScreenTools.defaultFontPixelWidth * 20
model: _activeJoystick.actions
onActivated: _activeJoystick.setButtonAction(modelData, textAt(index))
Component.onCompleted: currentIndex = find(_activeJoystick.buttonActions[modelData])
}
}
} // Repeater
} // Column
} // Column - right setting column
} // Row - Settings
} // Column - Left Main Column
// Right side column
Column {
id: rightColumn
anchors.top: parent.top
anchors.right: parent.right
width: defaultTextWidth * 35
spacing: 10
Image {
//width: parent.width
height: defaultTextHeight * 15
fillMode: Image.PreserveAspectFit
smooth: true
source: controller.imageHelp
}
// Axis monitor
Column {
width: parent.width
spacing: 5
QGCLabel { text: "Axis Monitor" }
Connections {
target: controller
onAxisValueChanged: {
if (axisMonitorRepeater.itemAt(axis)) {
axisMonitorRepeater.itemAt(axis).loader.item.axisValue = value
}
}
}
Repeater {
id: axisMonitorRepeater
model: controller.axisCount
width: parent.width
Row {
spacing: 5
// Need this to get to loader from Connections above
property Item loader: theLoader
QGCLabel {
id: axisLabel
text: modelData
}
Loader {
id: theLoader
anchors.verticalCenter: axisLabel.verticalCenter
height: rootQGCView.defaultTextHeight
width: 200
sourceComponent: axisMonitorDisplayComponent
property real defaultTextWidth: rootQGCView.defaultTextWidth
property bool mapped: true
readonly property bool reversed: false
}
}
}
} // Column - Axis Monitor
// Button monitor
Column {
width: parent.width
spacing: ScreenTools.defaultFontPixelHeight
QGCLabel { text: "Button Monitor" }
Connections {
target: _activeJoystick
onRawButtonPressedChanged: {
if (buttonMonitorRepeater.itemAt(index)) {
buttonMonitorRepeater.itemAt(index).pressed = pressed
}
}
}
Row {
spacing: -1
Repeater {
id: buttonMonitorRepeater
model: _activeJoystick.buttonCount
Rectangle {
width: ScreenTools.defaultFontPixelHeight * 1.5
height: width
border.width: 1
border.color: qgcPal.text
color: pressed ? qgcPal.buttonHighlight : qgcPal.button
property bool pressed
QGCLabel {
anchors.fill: parent
color: pressed ? qgcPal.buttonHighlightText : qgcPal.buttonText
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: modelData
}
}
} // Repeater
} // Row
} // Column - Axis Monitor
} // Column - Right Column
} // QGCViewPanel
}