From eb23e67e2f9a4563184a84d816705cc82614cba0 Mon Sep 17 00:00:00 2001 From: DoinLakeFlyer Date: Wed, 15 Apr 2020 14:15:57 -0700 Subject: [PATCH] Add support for multi-press joystick buttons --- src/Joystick/Joystick.cc | 26 ++++- src/VehicleSetup/JoystickConfigButtons.qml | 122 +++++++++++---------- 2 files changed, 89 insertions(+), 59 deletions(-) diff --git a/src/Joystick/Joystick.cc b/src/Joystick/Joystick.cc index ad40bbd18b0..aa5c3e8bc24 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 7f4f826f23e..9dc274c232c 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 } } }