From 5bf7a6c28d4d0de0b14dc32f39391b5cf88870af Mon Sep 17 00:00:00 2001 From: Max Paperno Date: Fri, 30 Dec 2016 16:36:29 -0500 Subject: [PATCH] Simulator key/mouse mapping improvements (#4175) * [simulator] Keyboard and mouse control adjustments: ~ Make kay/mouse navigation more consistent between radios and ensure keyboard events are always properly detected (eg. after clicking on a control); * Fix mouse wheel direction for rotary encoder emulation (fixes https://github.com/opentx/opentx/issues/4160); * Fix page up/down buttons on Horus (also #4160); ~ Horus rotary encoder can now be controlled with +/- keys (also keeps X/C, otherwise supersedes https://github.com/opentx/opentx/pull/4087 ); ~ DEL key now another alternative for ESC/BKSP (brings all controls to number pad); ~ "=" key now acts same as "+" key (+ requires SHIFT in main row on most US keyboards); * Fix controls direction when using mouse wheel over RC switches; + Add help text showing keyboard mappings for each radio type (activate on F1 key). * [simulator] Enable mouse wheel scrolling on radios w/out a rotary encoder (acts as +/- keys on X9D, PU/DN keys on 9X). --- .../src/simulation/simulatordialog-horus.ui | 23 +++++- .../src/simulation/simulatordialog-taranis.ui | 23 +++++- companion/src/simulation/simulatordialog.cpp | 78 ++++++++++++++----- companion/src/simulation/simulatordialog.h | 3 + .../src/simulation/simulatordialog9x.cpp | 21 +++-- .../src/simulation/simulatordialoghorus.cpp | 26 ++++++- .../src/simulation/simulatordialogtaranis.cpp | 17 +++- radio/src/targets/common/avr/board_avr.h | 2 + radio/src/targets/simu/opentxsimulator.cpp | 5 ++ radio/src/targets/sky9x/board.h | 2 + 10 files changed, 168 insertions(+), 32 deletions(-) diff --git a/companion/src/simulation/simulatordialog-horus.ui b/companion/src/simulation/simulatordialog-horus.ui index adb756852..7ada7458a 100644 --- a/companion/src/simulation/simulatordialog-horus.ui +++ b/companion/src/simulation/simulatordialog-horus.ui @@ -134,6 +134,9 @@ true + + true + QSlider::TicksBothSides @@ -208,6 +211,9 @@ true + + true + QSlider::TicksBothSides @@ -248,6 +254,9 @@ true + + true + QSlider::TicksBothSides @@ -288,6 +297,9 @@ true + + true + QSlider::TicksBothSides @@ -396,6 +408,9 @@ true + + true + QSlider::TicksBothSides @@ -436,6 +451,9 @@ true + + true + QSlider::TicksBothSides @@ -477,7 +495,7 @@ true - false + true QSlider::TicksBothSides @@ -553,6 +571,9 @@ true + + true + QSlider::TicksBothSides diff --git a/companion/src/simulation/simulatordialog-taranis.ui b/companion/src/simulation/simulatordialog-taranis.ui index 2eed724ff..e7fe3f205 100644 --- a/companion/src/simulation/simulatordialog-taranis.ui +++ b/companion/src/simulation/simulatordialog-taranis.ui @@ -446,6 +446,9 @@ true + + true + QSlider::TicksBothSides @@ -500,7 +503,7 @@ true - false + true QSlider::TicksBothSides @@ -561,6 +564,9 @@ true + + true + QSlider::TicksBothSides @@ -601,6 +607,9 @@ true + + true + QSlider::TicksBothSides @@ -641,6 +650,9 @@ true + + true + QSlider::TicksBothSides @@ -684,6 +696,9 @@ true + + true + QSlider::TicksBothSides @@ -724,6 +739,9 @@ true + + true + QSlider::TicksBothSides @@ -807,6 +825,9 @@ true + + true + QSlider::TicksBothSides diff --git a/companion/src/simulation/simulatordialog.cpp b/companion/src/simulation/simulatordialog.cpp index 38366c4ff..c6df3d5a2 100644 --- a/companion/src/simulation/simulatordialog.cpp +++ b/companion/src/simulation/simulatordialog.cpp @@ -54,12 +54,20 @@ SimulatorDialog::SimulatorDialog(QWidget * parent, SimulatorInterface *simulator middleButtonPressed(false) { setWindowFlags(Qt::Window); - //shorcut for telemetry simulator - // new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_T), this, SLOT(openTelemetrySimulator())); + grabKeyboard(); + + new QShortcut(QKeySequence(Qt::Key_F1), this, SLOT(showHelp())); new QShortcut(QKeySequence(Qt::Key_F4), this, SLOT(openTelemetrySimulator())); new QShortcut(QKeySequence(Qt::Key_F5), this, SLOT(openTrainerSimulator())); new QShortcut(QKeySequence(Qt::Key_F6), this, SLOT(openDebugOutput())); new QShortcut(QKeySequence(Qt::Key_F7), this, SLOT(luaReload())); + + keymapHelp.append(keymapHelp_t(tr("F1"), tr("Show Help/Keymap"))); + keymapHelp.append(keymapHelp_t(tr("F4"), tr("Open Telemetry Simulator"))); + keymapHelp.append(keymapHelp_t(tr("F5"), tr("Open Trainer Simulator"))); + keymapHelp.append(keymapHelp_t(tr("F6"), tr("Open Debug Output"))); + keymapHelp.append(keymapHelp_t(tr("F7"), tr("Reload Lua Scripts"))); + traceCallbackInstance = this; } @@ -91,29 +99,33 @@ void SimulatorDialog::showEvent(QShowEvent * event) vJoyRight->setStickConstraint(VirtualJoystickWidget::HOLD_Y, true); vJoyRight->setStickY(1); } + firstShow = false; } } void SimulatorDialog::mousePressEvent(QMouseEvent *event) { - if (event->button() == Qt::MidButton) { + if (event->button() == Qt::MidButton) middleButtonPressed = true; - } + else + event->ignore(); } void SimulatorDialog::mouseReleaseEvent(QMouseEvent *event) { - if (event->button() == Qt::MidButton) { + if (event->button() == Qt::MidButton) middleButtonPressed = false; - } + else + event->ignore(); } -void SimulatorDialog::wheelEvent (QWheelEvent *event) +void SimulatorDialog::wheelEvent(QWheelEvent *event) { - if ( event->delta() != 0) { - simulator->wheelEvent(event->delta() > 0 ? 1 : -1); - } + if (event->angleDelta().isNull()) + return; + QPoint numSteps = event->angleDelta() / 8 / 15 * -1; // one step per 15deg + simulator->wheelEvent(numSteps.y()); } void SimulatorDialog::traceCallback(const char * text) @@ -196,6 +208,25 @@ void SimulatorDialog::onDebugOutputClose() DebugOut = 0; } +void SimulatorDialog::showHelp() +{ + QString helpText = tr("Simulator Controls:"); + helpText += ""; + helpText += tr(""); + QString keyTemplate = ""; + foreach (keymapHelp_t pair, keymapHelp) + helpText += keyTemplate.arg(pair.first, pair.second); + helpText += "
Key/MouseAction
%1
%2
"; + + QMessageBox * msgBox = new QMessageBox(this); + msgBox->setAttribute(Qt::WA_DeleteOnClose); + msgBox->setWindowFlags(msgBox->windowFlags() | Qt::WindowStaysOnTopHint); + msgBox->setStandardButtons( QMessageBox::Ok ); + msgBox->setWindowTitle(tr("Simulator Help")); + msgBox->setText(helpText); + msgBox->setModal(false); + msgBox->show(); +} void SimulatorDialog::keyPressEvent (QKeyEvent *event) { @@ -206,25 +237,27 @@ void SimulatorDialog::keyPressEvent (QKeyEvent *event) break; case Qt::Key_Escape: case Qt::Key_Backspace: + case Qt::Key_Delete: buttonPressed = Qt::Key_Escape; break; + case Qt::Key_Plus: + case Qt::Key_Equal: + buttonPressed = Qt::Key_Plus; + break; case Qt::Key_Up: case Qt::Key_Down: case Qt::Key_Right: case Qt::Key_Left: case Qt::Key_Minus: - case Qt::Key_Plus: case Qt::Key_PageDown: - case Qt::Key_PageUp: + case Qt::Key_PageUp: + case Qt::Key_X: + case Qt::Key_C: buttonPressed = event->key(); break; - case Qt::Key_X: - simulator->wheelEvent(-1); + default: + event->ignore(); break; - case Qt::Key_C: - simulator->wheelEvent(1); - break; - } } @@ -235,16 +268,23 @@ void SimulatorDialog::keyReleaseEvent(QKeyEvent * event) case Qt::Key_Return: case Qt::Key_Escape: case Qt::Key_Backspace: + case Qt::Key_Delete: + case Qt::Key_Plus: + case Qt::Key_Equal: case Qt::Key_Up: case Qt::Key_Down: case Qt::Key_Right: case Qt::Key_Left: - case Qt::Key_Plus: case Qt::Key_Minus: case Qt::Key_PageDown: case Qt::Key_PageUp: + case Qt::Key_X: + case Qt::Key_C: buttonPressed = 0; break; + default: + event->ignore(); + break; } } diff --git a/companion/src/simulation/simulatordialog.h b/companion/src/simulation/simulatordialog.h index 12580c8d8..b0409c585 100644 --- a/companion/src/simulation/simulatordialog.h +++ b/companion/src/simulation/simulatordialog.h @@ -77,6 +77,7 @@ class SimulatorDialog : public QDialog virtual void traceCallback(const char * text); protected: + typedef QPair keymapHelp_t; template void initUi(T * ui); virtual void setLightOn(bool enable) { } virtual void updateBeepButton() { } @@ -98,6 +99,7 @@ class SimulatorDialog : public QDialog VirtualJoystickWidget *vJoyRight; QTimer *timer; QString windowName; + QVector keymapHelp; unsigned int backLight; bool lightOn; int switches; @@ -164,6 +166,7 @@ class SimulatorDialog : public QDialog void openDebugOutput(); void onDebugOutputClose(); void luaReload(); + void showHelp(); #ifdef JOYSTICKS void onjoystickAxisValueChanged(int axis, int value); diff --git a/companion/src/simulation/simulatordialog9x.cpp b/companion/src/simulation/simulatordialog9x.cpp index db4278c69..bf4753dff 100644 --- a/companion/src/simulation/simulatordialog9x.cpp +++ b/companion/src/simulation/simulatordialog9x.cpp @@ -18,7 +18,10 @@ * GNU General Public License for more details. */ +#include "simulatordialog.h" #include "ui_simulatordialog-9x.h" +#include "helpers.h" + uint32_t SimulatorDialog9X::switchstatus = 0; @@ -75,6 +78,14 @@ SimulatorDialog9X::SimulatorDialog9X(QWidget * parent, SimulatorInterface *simul if (g.simuSW()) restoreSwitches(); + keymapHelp.append(keymapHelp_t(tr("UP/PG-UP"), tr("[ UP ]"))); + keymapHelp.append(keymapHelp_t(tr("DN/PG-DN"), tr("[ DN ]"))); + keymapHelp.append(keymapHelp_t(tr("LEFT/+"), tr("[ + ]"))); + keymapHelp.append(keymapHelp_t(tr("RIGHT/-"), tr("[ - ]"))); + keymapHelp.append(keymapHelp_t(tr("ENTER/MOUSE-MID"), tr("[ MENU ]"))); + keymapHelp.append(keymapHelp_t(tr("DEL/BKSP/ESC"), tr("[ EXIT ]"))); + keymapHelp.append(keymapHelp_t(tr("WHEEL/PAD SCRL"), tr("[ UP ]/[ DN ] or Rotary Sel."))); + for (int i=0; isetProperty("index", i); connect(pots[i], SIGNAL(valueChanged(int)), this, SLOT(dialChanged(int))); @@ -154,12 +165,12 @@ void SimulatorDialog9X::getValues() }, { - buttonPressed == Qt::Key_Enter, + buttonPressed == Qt::Key_Enter || middleButtonPressed, buttonPressed == Qt::Key_Escape, - buttonPressed == Qt::Key_Down, - buttonPressed == Qt::Key_Up, - buttonPressed == Qt::Key_Right, - buttonPressed == Qt::Key_Left, + buttonPressed == Qt::Key_Down || buttonPressed == Qt::Key_PageDown, + buttonPressed == Qt::Key_Up || buttonPressed == Qt::Key_PageUp, + buttonPressed == Qt::Key_Right || buttonPressed == Qt::Key_Plus, + buttonPressed == Qt::Key_Left || buttonPressed == Qt::Key_Minus, }, middleButtonPressed, diff --git a/companion/src/simulation/simulatordialoghorus.cpp b/companion/src/simulation/simulatordialoghorus.cpp index f2f16bc33..e9b2f1a8f 100644 --- a/companion/src/simulation/simulatordialoghorus.cpp +++ b/companion/src/simulation/simulatordialoghorus.cpp @@ -49,7 +49,7 @@ SimulatorDialogHorus::SimulatorDialogHorus(QWidget * parent, SimulatorInterface polygon.setPoints(19, 29,232, 23,225, 19,218, 16,210, 14,200, 13,190, 14,179, 17,170, 20,162, 25,155, 30,149, 43,164, 37,172, 34,181, 33,190, 34,200, 37,209, 41,215, 44,219); ui->leftbuttons->addArea(polygon, Qt::Key_PageUp, "Horus/left_btn1.png"); polygon.setPoints(22, 32,234, 46,220, 52,225, 59,228, 68,230, 75,230, 83,229, 90,227, 95,224, 101,220, 114,234, 109,239, 103,242, 98,245, 91,248, 84,249, 77,250, 69,250, 60,249, 51,247, 44,243, 38,239); - ui->leftbuttons->addArea(polygon, Qt::Key_Escape, "Horus/left_btn2.png"); + ui->leftbuttons->addArea(polygon, Qt::Key_PageDown, "Horus/left_btn2.png"); ui->leftbuttons->addArea(9, 259, 34, 282, Qt::Key_Print, "Horus/left_scrnsht.png"); // install simulator TRACE hook @@ -63,6 +63,17 @@ SimulatorDialogHorus::SimulatorDialogHorus(QWidget * parent, SimulatorInterface if (g.simuSW()) restoreSwitches(); + keymapHelp.append(keymapHelp_t(tr("PG-UP"), tr("[ PgUp ]"))); + keymapHelp.append(keymapHelp_t(tr("PG-DN"), tr("[ PgDn ]"))); + keymapHelp.append(keymapHelp_t(tr("UP"), tr("[ MDL ]"))); + keymapHelp.append(keymapHelp_t(tr("DN/DEL/BKSP"), tr("[ RTN ]"))); + keymapHelp.append(keymapHelp_t(tr("LEFT"), tr("[ SYS ]"))); + keymapHelp.append(keymapHelp_t(tr("RIGHT"), tr("[ TELE ]"))); + keymapHelp.append(keymapHelp_t(tr("WHEEL/PAD SCRL"), tr("Rotary Selector"))); + keymapHelp.append(keymapHelp_t(tr("-/X"), tr("Rotary UP"))); + keymapHelp.append(keymapHelp_t(tr("+/C"), tr("Rotary DOWN"))); + keymapHelp.append(keymapHelp_t(tr("ENTER/MOUSE-MID"), tr("Selector Press"))); + connect(ui->leftbuttons, SIGNAL(buttonPressed(int)), this, SLOT(onButtonPressed(int))); connect(ui->rightbuttons, SIGNAL(buttonPressed(int)), this, SLOT(onButtonPressed(int))); connect(ui->teleSim, SIGNAL(released()), this, SLOT(openTelemetrySimulator())); @@ -118,10 +129,10 @@ void SimulatorDialogHorus::getValues() { buttonPressed == Qt::Key_PageUp, - buttonPressed == Qt::Key_Escape, + buttonPressed == Qt::Key_PageDown, buttonPressed == Qt::Key_Enter || middleButtonPressed, buttonPressed == Qt::Key_Up, - buttonPressed == Qt::Key_Down, + buttonPressed == Qt::Key_Down || buttonPressed == Qt::Key_Escape, buttonPressed == Qt::Key_Right, buttonPressed == Qt::Key_Left }, @@ -146,6 +157,15 @@ void SimulatorDialogHorus::getValues() }; simulator->setValues(inputs); + + if (buttonPressed == Qt::Key_Plus || buttonPressed == Qt::Key_C) { + simulator->wheelEvent(1); + buttonPressed = 0; // debounce, important + } + else if (buttonPressed == Qt::Key_Minus || buttonPressed == Qt::Key_X) { + simulator->wheelEvent(-1); + buttonPressed = 0; // debounce, important + } } void SimulatorDialogHorus::saveSwitches(void) diff --git a/companion/src/simulation/simulatordialogtaranis.cpp b/companion/src/simulation/simulatordialogtaranis.cpp index 04cc4f12e..f82fc802f 100644 --- a/companion/src/simulation/simulatordialogtaranis.cpp +++ b/companion/src/simulation/simulatordialogtaranis.cpp @@ -18,7 +18,10 @@ * GNU General Public License for more details. */ +#include "simulatordialog.h" #include "ui_simulatordialog-taranis.h" +#include "helpers.h" + uint32_t SimulatorDialogTaranis::switchstatus = 0; @@ -70,6 +73,14 @@ SimulatorDialogTaranis::SimulatorDialogTaranis(QWidget * parent, SimulatorInterf } } + keymapHelp.append(keymapHelp_t(tr("PG-UP"), tr("[ MENU ]"))); + keymapHelp.append(keymapHelp_t(tr("PG-DN"), tr("[ PAGE ]"))); + keymapHelp.append(keymapHelp_t(tr("DEL/BKSP/ESC"), tr("[ EXIT ]"))); + keymapHelp.append(keymapHelp_t(tr("+/UP"), tr("[ + ]"))); + keymapHelp.append(keymapHelp_t(tr("-/DN"), tr("[ - ]"))); + keymapHelp.append(keymapHelp_t(tr("ENTER/MOUSE-MID"), tr("[ ENT ]"))); + keymapHelp.append(keymapHelp_t(tr("WHEEL/PAD SCRL"), tr("[ + ]/[ - ] or Rotary Sel."))); + connect(ui->leftbuttons, SIGNAL(buttonPressed(int)), this, SLOT(onButtonPressed(int))); connect(ui->rightbuttons, SIGNAL(buttonPressed(int)), this, SLOT(onButtonPressed(int))); connect(ui->teleSim, SIGNAL(released()), this, SLOT(openTelemetrySimulator())); @@ -134,10 +145,10 @@ void SimulatorDialogTaranis::getValues() { buttonPressed == Qt::Key_PageUp, buttonPressed == Qt::Key_Escape, - buttonPressed == Qt::Key_Enter, + buttonPressed == Qt::Key_Enter || middleButtonPressed, buttonPressed == Qt::Key_PageDown, - buttonPressed == Qt::Key_Plus, - buttonPressed == Qt::Key_Minus + buttonPressed == Qt::Key_Plus || buttonPressed == Qt::Key_Up, + buttonPressed == Qt::Key_Minus || buttonPressed == Qt::Key_Down }, middleButtonPressed, diff --git a/radio/src/targets/common/avr/board_avr.h b/radio/src/targets/common/avr/board_avr.h index fb50df11f..45e458b85 100644 --- a/radio/src/targets/common/avr/board_avr.h +++ b/radio/src/targets/common/avr/board_avr.h @@ -56,7 +56,9 @@ enum EnumKeys KEY_ENTER=KEY_MENU, KEY_EXIT, KEY_DOWN, + KEY_MINUS = KEY_DOWN, KEY_UP, + KEY_PLUS = KEY_UP, KEY_RIGHT, KEY_LEFT, diff --git a/radio/src/targets/simu/opentxsimulator.cpp b/radio/src/targets/simu/opentxsimulator.cpp index 6740ef789..112a03b7c 100644 --- a/radio/src/targets/simu/opentxsimulator.cpp +++ b/radio/src/targets/simu/opentxsimulator.cpp @@ -158,6 +158,11 @@ void OpenTxSimulator::wheelEvent(int steps) { #if defined(ROTARY_ENCODER_NAVIGATION) ROTARY_ENCODER_NAVIGATION_VALUE += steps * ROTARY_ENCODER_GRANULARITY; +#else + if (steps > 0) + simuSetKey(KEY_MINUS, 1); + else if (steps < 0) + simuSetKey(KEY_PLUS, 1); #endif } diff --git a/radio/src/targets/sky9x/board.h b/radio/src/targets/sky9x/board.h index 0ca3f68f5..195b8a9f7 100644 --- a/radio/src/targets/sky9x/board.h +++ b/radio/src/targets/sky9x/board.h @@ -55,7 +55,9 @@ enum EnumKeys KEY_ENTER=KEY_MENU, KEY_EXIT, KEY_DOWN, + KEY_MINUS = KEY_DOWN, KEY_UP, + KEY_PLUS = KEY_UP, KEY_RIGHT, KEY_LEFT,