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).
This commit is contained in:
Max Paperno
2016-12-30 22:36:29 +01:00
committed by Bertrand Songis
parent 1d3b6721c6
commit 5bf7a6c28d
10 changed files with 168 additions and 32 deletions
@@ -134,6 +134,9 @@
<property name="invertedAppearance">
<bool>true</bool>
</property>
<property name="invertedControls">
<bool>true</bool>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBothSides</enum>
</property>
@@ -208,6 +211,9 @@
<property name="invertedAppearance">
<bool>true</bool>
</property>
<property name="invertedControls">
<bool>true</bool>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBothSides</enum>
</property>
@@ -248,6 +254,9 @@
<property name="invertedAppearance">
<bool>true</bool>
</property>
<property name="invertedControls">
<bool>true</bool>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBothSides</enum>
</property>
@@ -288,6 +297,9 @@
<property name="invertedAppearance">
<bool>true</bool>
</property>
<property name="invertedControls">
<bool>true</bool>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBothSides</enum>
</property>
@@ -396,6 +408,9 @@
<property name="invertedAppearance">
<bool>true</bool>
</property>
<property name="invertedControls">
<bool>true</bool>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBothSides</enum>
</property>
@@ -436,6 +451,9 @@
<property name="invertedAppearance">
<bool>true</bool>
</property>
<property name="invertedControls">
<bool>true</bool>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBothSides</enum>
</property>
@@ -477,7 +495,7 @@
<bool>true</bool>
</property>
<property name="invertedControls">
<bool>false</bool>
<bool>true</bool>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBothSides</enum>
@@ -553,6 +571,9 @@
<property name="invertedAppearance">
<bool>true</bool>
</property>
<property name="invertedControls">
<bool>true</bool>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBothSides</enum>
</property>
@@ -446,6 +446,9 @@
<property name="invertedAppearance">
<bool>true</bool>
</property>
<property name="invertedControls">
<bool>true</bool>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBothSides</enum>
</property>
@@ -500,7 +503,7 @@
<bool>true</bool>
</property>
<property name="invertedControls">
<bool>false</bool>
<bool>true</bool>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBothSides</enum>
@@ -561,6 +564,9 @@
<property name="invertedAppearance">
<bool>true</bool>
</property>
<property name="invertedControls">
<bool>true</bool>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBothSides</enum>
</property>
@@ -601,6 +607,9 @@
<property name="invertedAppearance">
<bool>true</bool>
</property>
<property name="invertedControls">
<bool>true</bool>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBothSides</enum>
</property>
@@ -641,6 +650,9 @@
<property name="invertedAppearance">
<bool>true</bool>
</property>
<property name="invertedControls">
<bool>true</bool>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBothSides</enum>
</property>
@@ -684,6 +696,9 @@
<property name="invertedAppearance">
<bool>true</bool>
</property>
<property name="invertedControls">
<bool>true</bool>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBothSides</enum>
</property>
@@ -724,6 +739,9 @@
<property name="invertedAppearance">
<bool>true</bool>
</property>
<property name="invertedControls">
<bool>true</bool>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBothSides</enum>
</property>
@@ -807,6 +825,9 @@
<property name="invertedAppearance">
<bool>true</bool>
</property>
<property name="invertedControls">
<bool>true</bool>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBothSides</enum>
</property>
+59 -19
View File
@@ -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 += "<table cellspacing=4 cellpadding=0>";
helpText += tr("<tr><th>Key/Mouse</td><th>Action</td></tr>");
QString keyTemplate = "<tr><td align='center'><pre>%1</pre></td><td align='center'>%2</td></tr>";
foreach (keymapHelp_t pair, keymapHelp)
helpText += keyTemplate.arg(pair.first, pair.second);
helpText += "</table>";
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;
}
}
@@ -77,6 +77,7 @@ class SimulatorDialog : public QDialog
virtual void traceCallback(const char * text);
protected:
typedef QPair<QString, QString> keymapHelp_t;
template <class T> 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_t> 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);
+16 -5
View File
@@ -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; i<pots.count(); i++) {
pots[i]->setProperty("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,
@@ -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)
@@ -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,
+2
View File
@@ -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,
@@ -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
}
+2
View File
@@ -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,