Qt: Analog inputs can be used for shortcuts

This commit is contained in:
Jeffrey Pfau 2015-04-18 01:11:41 -07:00
parent a0a3ac191a
commit 0c8a0cd0e4
6 changed files with 132 additions and 15 deletions

View File

@ -9,6 +9,7 @@ Features:
- Import/Export of GameShark/Action Replay snapshots
- Add "Step backwards" item for single increment rewind
- Deadzone estimation for game controllers
- Analog inputs can be used for shortcuts
Bugfixes:
- GBA: Fix timers not updating timing when writing to only the reload register
- All: Fix sanitize-deb script not cleaning up after itself

View File

@ -298,18 +298,20 @@ void InputController::testGamepad() {
for (auto& axis : m_activeAxes) {
bool newlyAboveThreshold = activeAxes.contains(axis);
GamepadAxisEvent* event = new GamepadAxisEvent(axis.first, axis.second, newlyAboveThreshold, this);
if (newlyAboveThreshold) {
GamepadAxisEvent* event = new GamepadAxisEvent(axis.first, axis.second, newlyAboveThreshold, this);
postPendingEvent(event->gbaKey());
QApplication::sendEvent(QApplication::focusWidget(), event);
if (!event->isAccepted()) {
clearPendingEvent(event->gbaKey());
}
} else if (oldAxes.contains(axis)) {
clearPendingEvent(event->gbaKey());
QApplication::sendEvent(QApplication::focusWidget(), event);
}
}
for (auto axis : oldAxes) {
GamepadAxisEvent* event = new GamepadAxisEvent(axis.first, axis.second, false, this);
clearPendingEvent(event->gbaKey());
QApplication::sendEvent(QApplication::focusWidget(), event);
}
if (!QApplication::focusWidget()) {
return;

View File

@ -40,6 +40,16 @@ QVariant ShortcutController::data(const QModelIndex& index, int role) const {
if (item->button() >= 0) {
return item->button();
}
if (item->axis() >= 0) {
char d = '\0';
if (item->direction() == GamepadAxisEvent::POSITIVE) {
d = '+';
}
if (item->direction() == GamepadAxisEvent::NEGATIVE) {
d = '-';
}
return QString("%1%2").arg(d).arg(item->axis());
}
break;
}
return QVariant();
@ -219,6 +229,7 @@ void ShortcutController::updateButton(const QModelIndex& index, int button) {
m_buttons.take(oldButton);
}
if (button >= 0) {
updateAxis(index, -1, GamepadAxisEvent::NEUTRAL);
m_buttons[button] = item;
}
if (m_config) {
@ -227,6 +238,38 @@ void ShortcutController::updateButton(const QModelIndex& index, int button) {
emit dataChanged(createIndex(index.row(), 0, index.internalPointer()), createIndex(index.row(), 2, index.internalPointer()));
}
void ShortcutController::updateAxis(const QModelIndex& index, int axis, GamepadAxisEvent::Direction direction) {
if (!index.isValid()) {
return;
}
const QModelIndex& parent = index.parent();
if (!parent.isValid()) {
return;
}
ShortcutItem* item = itemAt(index);
int oldAxis = item->axis();
GamepadAxisEvent::Direction oldDirection = item->direction();
item->setAxis(axis, direction);
if (oldAxis >= 0) {
m_axes.take(qMakePair(oldAxis, oldDirection));
}
if (axis >= 0 && direction != GamepadAxisEvent::NEUTRAL) {
updateButton(index, -1);
m_axes[qMakePair(axis, direction)] = item;
}
if (m_config) {
char d = '\0';
if (direction == GamepadAxisEvent::POSITIVE) {
d = '+';
}
if (direction == GamepadAxisEvent::NEGATIVE) {
d = '-';
}
m_config->setQtOption(item->name(), QString("%1%2").arg(d).arg(axis), AXIS_SECTION);
}
emit dataChanged(createIndex(index.row(), 0, index.internalPointer()), createIndex(index.row(), 2, index.internalPointer()));
}
void ShortcutController::clearKey(const QModelIndex& index) {
updateKey(index, QKeySequence());
}
@ -286,6 +329,31 @@ bool ShortcutController::eventFilter(QObject*, QEvent* event) {
event->accept();
return true;
}
if (event->type() == GamepadAxisEvent::Type()) {
GamepadAxisEvent* gae = static_cast<GamepadAxisEvent*>(event);
auto item = m_axes.find(qMakePair(gae->axis(), gae->direction()));
if (item == m_axes.end()) {
return false;
}
if (gae->isNew()) {
QAction* action = item.value()->action();
if (action && action->isEnabled()) {
action->trigger();
}
}
ShortcutItem::Functions pair = item.value()->functions();
if (gae->isNew()) {
if (pair.first) {
pair.first();
}
} else {
if (pair.second) {
pair.second();
}
}
event->accept();
return true;
}
return false;
}
@ -311,6 +379,30 @@ void ShortcutController::loadShortcuts(ShortcutItem* item) {
}
m_buttons[button.toInt()] = item;
}
QVariant axis = m_config->getQtOption(item->name(), AXIS_SECTION);
if (!axis.isNull()) {
int oldAxis = item->axis();
GamepadAxisEvent::Direction oldDirection = item->direction();
QString axisDesc = axis.toString();
if (axisDesc.size() >= 2) {
GamepadAxisEvent::Direction direction = GamepadAxisEvent::NEUTRAL;
if (axisDesc[0] == '-') {
direction = GamepadAxisEvent::NEGATIVE;
}
if (axisDesc[0] == '+') {
direction = GamepadAxisEvent::POSITIVE;
}
bool ok;
int axis = axisDesc.mid(1).toInt(&ok);
if (ok) {
item->setAxis(axis, direction);
if (oldAxis >= 0) {
m_axes.take(qMakePair(oldAxis, oldDirection));
}
m_axes[qMakePair(axis, direction)] = item;
}
}
}
}
QKeySequence ShortcutController::keyEventToSequence(const QKeyEvent* event) {
@ -339,6 +431,8 @@ ShortcutController::ShortcutItem::ShortcutItem(QAction* action, const QString& n
, m_menu(nullptr)
, m_name(name)
, m_button(-1)
, m_axis(-1)
, m_direction(GamepadAxisEvent::NEUTRAL)
, m_parent(parent)
{
m_visibleName = action->text()
@ -354,6 +448,8 @@ ShortcutController::ShortcutItem::ShortcutItem(ShortcutController::ShortcutItem:
, m_name(name)
, m_visibleName(visibleName)
, m_button(-1)
, m_axis(-1)
, m_direction(GamepadAxisEvent::NEUTRAL)
, m_parent(parent)
{
}
@ -362,6 +458,8 @@ ShortcutController::ShortcutItem::ShortcutItem(QMenu* menu, ShortcutItem* parent
: m_action(nullptr)
, m_menu(menu)
, m_button(-1)
, m_axis(-1)
, m_direction(GamepadAxisEvent::NEUTRAL)
, m_parent(parent)
{
if (menu) {
@ -389,3 +487,8 @@ void ShortcutController::ShortcutItem::setShortcut(const QKeySequence& shortcut)
m_action->setShortcut(shortcut);
}
}
void ShortcutController::ShortcutItem::setAxis(int axis, GamepadAxisEvent::Direction direction) {
m_axis = axis;
m_direction = direction;
}

View File

@ -6,6 +6,8 @@
#ifndef QGBA_SHORTCUT_MODEL
#define QGBA_SHORTCUT_MODEL
#include "GamepadAxisEvent.h"
#include <QAbstractItemModel>
#include <QKeySequence>
@ -26,6 +28,7 @@ Q_OBJECT
private:
constexpr static const char* const KEY_SECTION = "shortcutKey";
constexpr static const char* const BUTTON_SECTION = "shortcutButton";
constexpr static const char* const AXIS_SECTION = "shortcutAxis";
class ShortcutItem {
public:
@ -53,6 +56,9 @@ private:
int button() const { return m_button; }
void setShortcut(const QKeySequence& sequence);
void setButton(int button) { m_button = button; }
int axis() const { return m_axis; }
GamepadAxisEvent::Direction direction() const { return m_direction; }
void setAxis(int axis, GamepadAxisEvent::Direction direction);
bool operator==(const ShortcutItem& other) const { return m_menu == other.m_menu && m_action == other.m_action; }
@ -64,6 +70,8 @@ private:
QString m_name;
QString m_visibleName;
int m_button;
int m_axis;
GamepadAxisEvent::Direction m_direction;
QList<ShortcutItem> m_items;
ShortcutItem* m_parent;
};
@ -91,6 +99,7 @@ public:
void updateKey(const QModelIndex& index, const QKeySequence& keySequence);
void updateButton(const QModelIndex& index, int button);
void updateAxis(const QModelIndex& index, int axis, GamepadAxisEvent::Direction direction);
void clearKey(const QModelIndex& index);
void clearButton(const QModelIndex& index);
@ -108,6 +117,7 @@ private:
ShortcutItem m_rootMenu;
QMap<QMenu*, ShortcutItem*> m_menuMap;
QMap<int, ShortcutItem*> m_buttons;
QMap<QPair<int, GamepadAxisEvent::Direction>, ShortcutItem*> m_axes;
QMap<QKeySequence, ShortcutItem*> m_heldKeys;
ConfigController* m_config;
};

View File

@ -22,6 +22,7 @@ ShortcutView::ShortcutView(QWidget* parent)
connect(m_ui.keySequenceEdit, SIGNAL(keySequenceChanged(const QKeySequence&)), this, SLOT(updateKey(const QKeySequence&)));
connect(m_ui.keyEdit, SIGNAL(valueChanged(int)), this, SLOT(updateButton(int)));
connect(m_ui.keyEdit, SIGNAL(axisChanged(int, int)), this, SLOT(updateAxis(int, int)));
connect(m_ui.shortcutTable, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(load(const QModelIndex&)));
connect(m_ui.clearButton, SIGNAL(clicked()), this, SLOT(clear()));
}
@ -31,15 +32,6 @@ void ShortcutView::setController(ShortcutController* controller) {
m_ui.shortcutTable->setModel(controller);
}
bool ShortcutView::event(QEvent* event) {
if (event->type() == GamepadButtonEvent::Down()) {
updateButton(static_cast<GamepadButtonEvent*>(event)->value());
event->accept();
return true;
}
return QWidget::event(event);
}
bool ShortcutView::eventFilter(QObject*, QEvent* event) {
if (event->type() == QEvent::KeyPress) {
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
@ -106,5 +98,12 @@ void ShortcutView::updateButton(int button) {
return;
}
m_controller->updateButton(m_ui.shortcutTable->selectionModel()->currentIndex(), button);
}
void ShortcutView::updateAxis(int axis, int direction) {
if (!m_controller || m_controller->isMenuAt(m_ui.shortcutTable->selectionModel()->currentIndex())) {
return;
}
m_controller->updateAxis(m_ui.shortcutTable->selectionModel()->currentIndex(), axis, static_cast<GamepadAxisEvent::Direction>(direction));
}

View File

@ -6,6 +6,8 @@
#ifndef QGBA_SHORTCUT_VIEW
#define QGBA_SHORTCUT_VIEW
#include "GamepadAxisEvent.h"
#include <QWidget>
#include "ui_ShortcutView.h"
@ -23,7 +25,6 @@ public:
void setController(ShortcutController* controller);
protected:
virtual bool event(QEvent* event) override;
virtual bool eventFilter(QObject* obj, QEvent* event) override;
private slots:
@ -31,6 +32,7 @@ private slots:
void clear();
void updateKey(const QKeySequence&);
void updateButton(int button);
void updateAxis(int axis, int direction);
private:
Ui::ShortcutView m_ui;