QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
JoystickComponentButtons.qml
Go to the documentation of this file.
1import QtQuick
2import QtQuick.Controls
3import QtQuick.Dialogs
4import QtQuick.Layouts
5
6import QGroundControl
7import QGroundControl.Controls
8import QGroundControl.VehicleSetup
9import QGroundControl.FactControls
10
11ColumnLayout {
12 spacing: ScreenTools.defaultFontPixelHeight / 2
13
14 required property var joystick
15 required property var controller
16
17 property int _maxButtons: 64
18
19 QGCLabel {
20 Layout.preferredWidth: parent.width
21 wrapMode: Text.WordWrap
22 text: qsTr("Multiple buttons that have the same action must be pressed simultaneously to invoke the action.")
23 }
24
25 RowLayout {
26 id: buttonAssignmentRow
27 spacing: ScreenTools.defaultFontPixelWidth
28
29 property int selectedButtonIndex: 0
30 property var _assignedButtonModel: assignedButtonModel
31
32 function _rebuildAssignedButtonModel() {
33 assignedButtonModel.clear()
34 let buttonActions = joystick.buttonActions
35 for (let i = 0; i < joystick.buttonCount; i++) {
36 if (buttonActions[i] !== joystick.buttonActionNone) {
37 assignedButtonModel.append( { "buttonIndex": i, "buttonAction": buttonActions[i], "repeat": joystick.getButtonRepeat(i) } )
38 }
39 }
40 }
41
42 Component.onCompleted: _rebuildAssignedButtonModel()
43 Connections { target: joystick; function onButtonActionsChanged() { buttonAssignmentRow._rebuildAssignedButtonModel() } }
44
45 ListModel {
46 id: assignedButtonModel
47 }
48
49 QGCComboBox {
50 id: buttonIndexCombo
51 model: joystick.buttonCount
52
53 onActivated: (index) => { buttonAssignmentRow.selectedButtonIndex = index }
54 }
55
56 QGCComboBox {
57 id: buttonActionCombo
58 model: joystick.assignableActionTitles
59 sizeToContents: true
60
61 onActivated: (index) => { joystick.setButtonAction(buttonAssignmentRow.selectedButtonIndex, textAt(index)) }
62
63 function _findCurrentButtonAction() {
64 let buttonActionIndex = find(joystick.buttonActions[buttonAssignmentRow.selectedButtonIndex])
65 if (buttonActionIndex < 0) {
66 buttonActionIndex = 0
67 }
68 currentIndex = buttonActionIndex
69 }
70
71 Component.onCompleted: _findCurrentButtonAction()
72 Connections { target: buttonAssignmentRow; function onSelectedButtonIndexChanged() { buttonActionCombo._findCurrentButtonAction() } }
73 }
74
75 QGCCheckBox {
76 text: qsTr("Repeat")
77 checked: joystick.getButtonRepeat(buttonAssignmentRow.selectedButtonIndex)
78 enabled: buttonActionCombo.currentIndex === -1 ? false : (joystick.assignableActions.get(buttonActionCombo.currentIndex) ? joystick.assignableActions.get(buttonActionCombo.currentIndex).canRepeat : false)
79
80 onClicked: {
81 joystick.setButtonRepeat(buttonAssignmentRow.selectedButtonIndex, checked)
82 buttonAssignmentRow._rebuildAssignedButtonModel()
83 }
84 }
85 }
86
87 GridLayout {
88 rows: buttonAssignmentRow._assignedButtonModel.count
89 columnSpacing: ScreenTools.defaultFontPixelWidth
90 rowSpacing: 0
91 flow: GridLayout.TopToBottom
92
93 Repeater {
94 model: buttonAssignmentRow._assignedButtonModel
95 QGCLabel { text: buttonIndex }
96 }
97 Repeater {
98 model: buttonAssignmentRow._assignedButtonModel
99 QGCLabel { text: buttonAction }
100 }
101 Repeater {
102 model: buttonAssignmentRow._assignedButtonModel
103 QGCLabel { text: repeat ? "Repeat" : "" }
104 }
105 }
106
107 /*Column {
108 id: buttonCol
109 Layout.fillWidth: true
110 visible: globals.activeVehicle.supports.jsButton
111 spacing: ScreenTools.defaultFontPixelHeight / 3
112
113 Row {
114 spacing: ScreenTools.defaultFontPixelWidth
115 QGCLabel {
116 horizontalAlignment: Text.AlignHCenter
117 width: ScreenTools.defaultFontPixelHeight * 1.5
118 text: qsTr("#")
119 }
120 QGCLabel {
121 width: ScreenTools.defaultFontPixelWidth * 26
122 text: qsTr("Function: ")
123 }
124 QGCLabel {
125 width: ScreenTools.defaultFontPixelWidth * 26
126 visible: globals.activeVehicle.supports.jsButton
127 text: qsTr("Shift Function: ")
128 }
129 }
130 Repeater {
131 id: jsButtonActionRepeater
132 model: joystick ? Math.min(joystick.buttonCount, _maxButtons) : 0
133
134 Row {
135 spacing: ScreenTools.defaultFontPixelWidth
136 visible: globals.activeVehicle.supports.jsButton
137 property var parameterName: `BTN${index}_FUNCTION`
138 property var parameterShiftName: `BTN${index}_SFUNCTION`
139 property bool hasFirmwareSupport: controller.parameterExists(-1, parameterName)
140
141 property bool pressed
142 property var currentAssignableAction: joystick ? joystick.assignableActions.get(buttonActionCombo.currentIndex) : null
143
144 Rectangle {
145 anchors.verticalCenter: parent.verticalCenter
146 width: ScreenTools.defaultFontPixelHeight * 1.5
147 height: width
148 border.width: 1
149 border.color: qgcPal.text
150 color: pressed ? qgcPal.buttonHighlight : qgcPal.button
151
152
153 QGCLabel {
154 anchors.fill: parent
155 color: pressed ? qgcPal.buttonHighlightText : qgcPal.buttonText
156 horizontalAlignment: Text.AlignHCenter
157 verticalAlignment: Text.AlignVCenter
158 text: modelData
159 }
160 }
161
162 QGCComboBox {
163 id: buttonActionCombo
164 width: ScreenTools.defaultFontPixelWidth * 26
165 property Fact fact: controller.parameterExists(-1, parameterName) ? controller.getParameterFact(-1, parameterName) : null
166 property Fact fact_shift: controller.parameterExists(-1, parameterShiftName) ? controller.getParameterFact(-1, parameterShiftName) : null
167 property var factOptions: fact ? fact.enumStrings : [];
168 property var qgcActions: joystick.assignableActionTitles.filter(
169 function (s) {
170 return [
171 s.includes("Camera"),
172 s.includes("Stream"),
173 s.includes("Stream"),
174 s.includes("Zoom"),
175 s.includes("Gimbal"),
176 s.includes("No Action")
177 ].some(Boolean)
178 }
179 )
180
181 model: [...qgcActions, ...factOptions]
182 property var isFwAction: currentIndex >= qgcActions.length
183 sizeToContents: true
184
185 function _findCurrentButtonAction() {
186 // Find the index in the dropdown of the current action, checks FW and QGC actions
187 if (joystick) {
188 if (fact && fact.value > 0) {
189 // This is a firmware function
190 currentIndex = qgcActions.length + fact.enumIndex
191 // For sanity reasons, make sure qgc is set to "no action" if the firmware is set to do something
192 joystick.setButtonAction(modelData, "No Action")
193 } else {
194 // If there is not firmware function, check QGC ones
195 currentIndex = find(joystick.buttonActions[modelData])
196 }
197 }
198 }
199
200 Component.onCompleted: _findCurrentButtonAction()
201 onModelChanged: _findCurrentButtonAction()
202 onActivated: function (optionIndex) {
203 var func = textAt(optionIndex)
204 if (factOptions.indexOf(func) > -1) {
205 // This is a FW action, set parameter to the action and set QGC's handler to No Action
206 fact.enumStringValue = func
207 joystick.setButtonAction(modelData, "No Action")
208 } else {
209 // This is a QGC action, set parameters to Disabled and QGC to the desired action
210 joystick.setButtonAction(modelData, func)
211 fact.value = 0
212 fact_shift.value = 0
213 }
214 }
215 }
216 QGCCheckBox {
217 id: repeatCheck
218 text: qsTr("Repeat")
219 enabled: currentAssignableAction && joystick.calibrated && currentAssignableAction.canRepeat
220 visible: !globals.activeVehicle.supports.jsButton
221
222 onClicked: {
223 joystick.setButtonRepeat(modelData, checked)
224 }
225 Component.onCompleted: {
226 if (joystick) {
227 checked = joystick.getButtonRepeat(modelData)
228 }
229 }
230 anchors.verticalCenter: parent.verticalCenter
231 }
232 Item {
233 width: ScreenTools.defaultFontPixelWidth * 2
234 height: 1
235 }
236
237 FactComboBox {
238 id: shiftJSButtonActionCombo
239 width: ScreenTools.defaultFontPixelWidth * 26
240 fact: controller.parameterExists(-1, parameterShiftName) ? controller.getParameterFact(-1, parameterShiftName) : null;
241 indexModel: false
242 visible: buttonActionCombo.isFwAction
243 sizeToContents: true
244 }
245
246 QGCLabel {
247 text: qsTr("QGC functions do not support shift actions")
248 width: ScreenTools.defaultFontPixelWidth * 15
249 visible: hasFirmwareSupport && !buttonActionCombo.isFwAction
250 anchors.verticalCenter: parent.verticalCenter
251 }
252 QGCLabel {
253 text: qsTr("No firmware support")
254 width: ScreenTools.defaultFontPixelWidth * 15
255 visible: !hasFirmwareSupport
256 anchors.verticalCenter: parent.verticalCenter
257 }
258 }
259 }
260 }*/
261}