7import QGroundControl.Controls
8import QGroundControl.VehicleSetup
9import QGroundControl.FactControls
12 spacing: ScreenTools.defaultFontPixelHeight / 2
14 required property var joystick
15 required property var controller
17 property int _maxButtons: 64
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.")
26 id: buttonAssignmentRow
27 spacing: ScreenTools.defaultFontPixelWidth
29 property int selectedButtonIndex: 0
30 property var _assignedButtonModel: assignedButtonModel
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) } )
42 Component.onCompleted: _rebuildAssignedButtonModel()
43 Connections { target: joystick; function onButtonActionsChanged() { buttonAssignmentRow._rebuildAssignedButtonModel() } }
46 id: assignedButtonModel
51 model: joystick.buttonCount
53 onActivated: (index) => { buttonAssignmentRow.selectedButtonIndex = index }
58 model: joystick.assignableActionTitles
61 onActivated: (index) => { joystick.setButtonAction(buttonAssignmentRow.selectedButtonIndex, textAt(index)) }
63 function _findCurrentButtonAction() {
64 let buttonActionIndex = find(joystick.buttonActions[buttonAssignmentRow.selectedButtonIndex])
65 if (buttonActionIndex < 0) {
68 currentIndex = buttonActionIndex
71 Component.onCompleted: _findCurrentButtonAction()
72 Connections { target: buttonAssignmentRow; function onSelectedButtonIndexChanged() { buttonActionCombo._findCurrentButtonAction() } }
77 checked: joystick.getButtonRepeat(buttonAssignmentRow.selectedButtonIndex)
78 enabled: buttonActionCombo.currentIndex === -1 ? false : (joystick.assignableActions.get(buttonActionCombo.currentIndex) ? joystick.assignableActions.get(buttonActionCombo.currentIndex).canRepeat : false)
81 joystick.setButtonRepeat(buttonAssignmentRow.selectedButtonIndex, checked)
82 buttonAssignmentRow._rebuildAssignedButtonModel()
88 rows: buttonAssignmentRow._assignedButtonModel.count
89 columnSpacing: ScreenTools.defaultFontPixelWidth
91 flow: GridLayout.TopToBottom
94 model: buttonAssignmentRow._assignedButtonModel
95 QGCLabel { text: buttonIndex }
98 model: buttonAssignmentRow._assignedButtonModel
99 QGCLabel { text: buttonAction }
102 model: buttonAssignmentRow._assignedButtonModel
103 QGCLabel { text: repeat ? "Repeat" : "" }
109 Layout.fillWidth: true
110 visible: globals.activeVehicle.supports.jsButton
111 spacing: ScreenTools.defaultFontPixelHeight / 3
114 spacing: ScreenTools.defaultFontPixelWidth
116 horizontalAlignment: Text.AlignHCenter
117 width: ScreenTools.defaultFontPixelHeight * 1.5
121 width: ScreenTools.defaultFontPixelWidth * 26
122 text: qsTr("Function: ")
125 width: ScreenTools.defaultFontPixelWidth * 26
126 visible: globals.activeVehicle.supports.jsButton
127 text: qsTr("Shift Function: ")
131 id: jsButtonActionRepeater
132 model: joystick ? Math.min(joystick.buttonCount, _maxButtons) : 0
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)
141 property bool pressed
142 property var currentAssignableAction: joystick ? joystick.assignableActions.get(buttonActionCombo.currentIndex) : null
145 anchors.verticalCenter: parent.verticalCenter
146 width: ScreenTools.defaultFontPixelHeight * 1.5
149 border.color: qgcPal.text
150 color: pressed ? qgcPal.buttonHighlight : qgcPal.button
155 color: pressed ? qgcPal.buttonHighlightText : qgcPal.buttonText
156 horizontalAlignment: Text.AlignHCenter
157 verticalAlignment: Text.AlignVCenter
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(
171 s.includes("Camera"),
172 s.includes("Stream"),
173 s.includes("Stream"),
175 s.includes("Gimbal"),
176 s.includes("No Action")
181 model: [...qgcActions, ...factOptions]
182 property var isFwAction: currentIndex >= qgcActions.length
185 function _findCurrentButtonAction() {
186 // Find the index in the dropdown of the current action, checks FW and QGC actions
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")
194 // If there is not firmware function, check QGC ones
195 currentIndex = find(joystick.buttonActions[modelData])
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")
209 // This is a QGC action, set parameters to Disabled and QGC to the desired action
210 joystick.setButtonAction(modelData, func)
219 enabled: currentAssignableAction && joystick.calibrated && currentAssignableAction.canRepeat
220 visible: !globals.activeVehicle.supports.jsButton
223 joystick.setButtonRepeat(modelData, checked)
225 Component.onCompleted: {
227 checked = joystick.getButtonRepeat(modelData)
230 anchors.verticalCenter: parent.verticalCenter
233 width: ScreenTools.defaultFontPixelWidth * 2
238 id: shiftJSButtonActionCombo
239 width: ScreenTools.defaultFontPixelWidth * 26
240 fact: controller.parameterExists(-1, parameterShiftName) ? controller.getParameterFact(-1, parameterShiftName) : null;
242 visible: buttonActionCombo.isFwAction
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
253 text: qsTr("No firmware support")
254 width: ScreenTools.defaultFontPixelWidth * 15
255 visible: !hasFirmwareSupport
256 anchors.verticalCenter: parent.verticalCenter