diff --git a/src/Joystick/Joystick.cc b/src/Joystick/Joystick.cc index ad40bbd18b063eeebf039e686a5c17dec05d3d37..aa5c3e8bc24ab53b6f9469ed5d9b0a2340e7f4e4 100644 --- a/src/Joystick/Joystick.cc +++ b/src/Joystick/Joystick.cc @@ -515,12 +515,32 @@ void Joystick::_handleButtons() QString buttonAction = _buttonActionArray[buttonIndex]->action; if(buttonAction.isEmpty() || buttonAction == _buttonActionNone) continue; - //-- Process single button if(!_buttonActionArray[buttonIndex]->repeat) { //-- This button just went down if(_rgButtonValues[buttonIndex] == BUTTON_DOWN) { - qCDebug(JoystickLog) << "Single button triggered" << buttonIndex << buttonAction; - _executeButtonAction(buttonAction, true); + // Check for a multi-button action + QList rgButtons = { buttonIndex }; + bool executeButtonAction = true; + for (int multiIndex = 0; multiIndex < _totalButtonCount; multiIndex++) { + if (multiIndex != buttonIndex) { + if (_buttonActionArray[multiIndex] && _buttonActionArray[multiIndex]->action == buttonAction) { + // We found a multi-button action + if (_rgButtonValues[multiIndex] == BUTTON_DOWN || _rgButtonValues[multiIndex] == BUTTON_REPEAT) { + // So far so good + rgButtons.append(multiIndex); + continue; + } else { + // We are missing a press we need + executeButtonAction = false; + break; + } + } + } + } + if (executeButtonAction) { + qCDebug(JoystickLog) << "Action triggered" << rgButtons << buttonAction; + _executeButtonAction(buttonAction, true); + } } } else { //-- Process repeat buttons diff --git a/src/VehicleSetup/JoystickConfigButtons.qml b/src/VehicleSetup/JoystickConfigButtons.qml index 7f4f826f23e9693adb2ca820e036006a92deb98f..9dc274c232c0ba8fabe0de343107da8564fbd396 100644 --- a/src/VehicleSetup/JoystickConfigButtons.qml +++ b/src/VehicleSetup/JoystickConfigButtons.qml @@ -22,7 +22,7 @@ import QGroundControl.FactControls 1.0 Item { width: availableWidth - height: (activeVehicle.supportsJSButton ? buttonCol.height : buttonFlow.height) + (ScreenTools.defaultFontPixelHeight * 2) + height: (activeVehicle.supportsJSButton ? buttonCol.height : flowColumn.height) + (ScreenTools.defaultFontPixelHeight * 2) Connections { target: _activeJoystick onRawButtonPressedChanged: { @@ -34,66 +34,76 @@ Item { } } } - Flow { - id: buttonFlow - width: parent.width - spacing: ScreenTools.defaultFontPixelWidth - visible: !activeVehicle.supportsJSButton - anchors.centerIn: parent - Repeater { - id: buttonActionRepeater - model: _activeJoystick ? Math.min(_activeJoystick.totalButtonCount, _maxButtons) : [] - Row { - spacing: ScreenTools.defaultFontPixelWidth - property bool pressed - property var currentAssignableAction: _activeJoystick ? _activeJoystick.assignableActions.get(buttonActionCombo.currentIndex) : null - 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 * 26 - model: _activeJoystick ? _activeJoystick.assignableActionTitles : [] - onActivated: { - _activeJoystick.setButtonAction(modelData, textAt(index)) - } - Component.onCompleted: { - if(_activeJoystick) { - var i = find(_activeJoystick.buttonActions[modelData]) - if(i < 0) i = 0 - currentIndex = i + ColumnLayout { + id: flowColumn + y: ScreenTools.defaultFontPixelHeight / 2 + width: parent.width + spacing: ScreenTools.defaultFontPixelHeight / 2 + QGCLabel { + Layout.preferredWidth: parent.width + wrapMode: Text.WordWrap + text: qsTr("Assigning the same action to multiple buttons requires the press of all those buttons for the action to be taken. This is useful to prevent accidental button presses for critical actions like Arm or Emergency Stop.") + } + Flow { + id: buttonFlow + Layout.preferredWidth: parent.width + spacing: ScreenTools.defaultFontPixelWidth + visible: !activeVehicle.supportsJSButton + Repeater { + id: buttonActionRepeater + model: _activeJoystick ? Math.min(_activeJoystick.totalButtonCount, _maxButtons) : [] + Row { + spacing: ScreenTools.defaultFontPixelWidth + property bool pressed + property var currentAssignableAction: _activeJoystick ? _activeJoystick.assignableActions.get(buttonActionCombo.currentIndex) : null + 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 } } - } - QGCCheckBox { - id: repeatCheck - text: qsTr("Repeat") - enabled: currentAssignableAction && _activeJoystick.calibrated && currentAssignableAction.canRepeat - onClicked: { - _activeJoystick.setButtonRepeat(modelData, checked) + QGCComboBox { + id: buttonActionCombo + width: ScreenTools.defaultFontPixelWidth * 26 + model: _activeJoystick ? _activeJoystick.assignableActionTitles : [] + onActivated: { + _activeJoystick.setButtonAction(modelData, textAt(index)) + } + Component.onCompleted: { + if(_activeJoystick) { + var i = find(_activeJoystick.buttonActions[modelData]) + if(i < 0) i = 0 + currentIndex = i + } + } } - Component.onCompleted: { - if(_activeJoystick) { - checked = _activeJoystick.getButtonRepeat(modelData) + QGCCheckBox { + id: repeatCheck + text: qsTr("Repeat") + enabled: currentAssignableAction && _activeJoystick.calibrated && currentAssignableAction.canRepeat + onClicked: { + _activeJoystick.setButtonRepeat(modelData, checked) + } + Component.onCompleted: { + if(_activeJoystick) { + checked = _activeJoystick.getButtonRepeat(modelData) + } } + anchors.verticalCenter: parent.verticalCenter + } + Item { + width: ScreenTools.defaultFontPixelWidth * 2 + height: 1 } - anchors.verticalCenter: parent.verticalCenter - } - Item { - width: ScreenTools.defaultFontPixelWidth * 2 - height: 1 } } }