Qt: Restore most functionality in input revamp
@@ -54,9 +54,6 @@ #endif
m_gamepadTimer.setInterval(50); m_gamepadTimer.start(); - m_autofireMenu = m_inputModel->root()->addItem(tr("Autofire"), "autofire"); - m_inputMenu = m_inputModel->root()->addItem(tr("Bindings"), "bindings"); - mInputMapInit(&m_inputMap, &GBAInputInfo); #ifdef BUILD_SDL@@ -632,20 +629,6 @@ m_focusParent = m_topLevel;
} } -void InputController::setupCallback(GameController* controller) { - [this, controller](InputItem* item, int key, bool down) { - if (item->parent() == m_autofireMenu) { - controller->setAutofire(key, down); - } else { - if (down) { - controller->keyPressed(key); - } else { - controller->keyReleased(key); - } - } - }; -} - void InputController::doBindKey(const QModelIndex& index, int key) { int coreKey = m_inputModel->itemAt(index)->key(); if (coreKey < 0) {@@ -699,26 +682,48 @@ event->accept();
return true; } - // TODO + InputItem* item = m_inputModel->itemForShortcut(key); + if (item) { + item->trigger(event->type() == QEvent::KeyPress); + event->accept(); + return true; + } } if (event->type() == GamepadButtonEvent::Down() || event->type() == GamepadButtonEvent::Up()) { GamepadButtonEvent* gbe = static_cast<GamepadButtonEvent*>(event); - // TODO + InputItem* item = m_inputModel->itemForButton(gbe->value()); + if (item) { + item->trigger(event->type() == GamepadButtonEvent::Down()); + event->accept(); + return true; + } } if (event->type() == GamepadAxisEvent::Type()) { GamepadAxisEvent* gae = static_cast<GamepadAxisEvent*>(event); - // TODO + InputItem* item = m_inputModel->itemForAxis(gae->axis(), gae->direction()); + if (item) { + item->trigger(event->type() == gae->isNew()); + event->accept(); + return true; + } } return false; } +InputItem* InputController::itemForKey(int key) { + if (key < 0 || key >= m_inputMap.info->nKeys) { + return nullptr; + } + return m_inputModel->itemAt(QString("key%0").arg(m_inputMap.info->keyId[key])); +} + void InputController::restoreModel() { bool signalsBlocked = m_inputModel->blockSignals(true); int nKeys = m_inputMap.info->nKeys; - /*for (int i = 0; i < nKeys; ++i) { - InputItem* item = m_inputModel->itemForKey(i); + for (int i = 0; i < nKeys; ++i) { + InputItem* item = itemForKey(i); if (item) { int key = mInputQueryBinding(&m_inputMap, KEYBOARD, i); if (key >= 0) {@@ -737,22 +742,31 @@ #endif
} } #ifdef BUILD_SDL + struct Context { + InputModel* model; + InputController* controller; + } context { + m_inputModel, + this + }; mInputEnumerateAxes(&m_inputMap, SDL_BINDING_BUTTON, [](int axis, const struct mInputAxis* description, void* user) { - InputModel* model = static_cast<InputModel*>(user); + Context* context = static_cast<Context*>(user); + InputModel* model = context->model; + InputController* controller = context->controller; InputItem* item; - if (description->highDirection >= 0) { - item = model->itemForKey(description->highDirection); + if (description->highDirection >= 0 && description->highDirection < controller->m_inputMap.info->nKeys) { + item = controller->itemForKey(description->highDirection); if (item) { item->setAxis(axis, GamepadAxisEvent::POSITIVE); } } - if (description->lowDirection >= 0) { - item = model->itemForKey(description->lowDirection); + if (description->lowDirection >= 0 && description->lowDirection < controller->m_inputMap.info->nKeys) { + item = controller->itemForKey(description->lowDirection); if (item) { item->setAxis(axis, GamepadAxisEvent::NEGATIVE); } } - }, m_inputModel); -#endif*/ + }, &context); +#endif m_inputModel->blockSignals(signalsBlocked); }
@@ -89,8 +89,6 @@
mRumble* rumble(); mRotationSource* rotationSource(); - void setupCallback(GameController* controller); - signals: void profileLoaded(const QString& profile);@@ -119,6 +117,8 @@ bool hasPendingEvent(int key) const;
void sendGamepadEvent(QEvent*); void restoreModel(); + InputItem* itemForKey(int key); + InputModel* m_inputModel = nullptr; mInputMap m_inputMap; ConfigController* m_config = nullptr;@@ -135,9 +135,6 @@ bool m_playerAttached = false;
#endif QVector<int> m_deadzones; - - InputItem* m_inputMenu; - InputItem* m_autofireMenu; QSet<int> m_activeButtons; QSet<QPair<int, GamepadAxisEvent::Direction>> m_activeAxes;
@@ -43,7 +43,7 @@ }
InputItem::InputItem(int key, const QString& visibleName, const QString& name, InputItem* parent) : QObject(parent) - , m_keys(key) + , m_key(key) , m_name(name) , m_visibleName(visibleName) , m_parent(parent)@@ -84,3 +84,15 @@ m_axis = axis;
m_direction = direction; emit axisBound(this, axis, direction); } + +void InputItem::trigger(bool active) { + if (active) { + if (m_functions.first) { + m_functions.first(); + } + } else { + if (m_functions.second) { + m_functions.second(); + } + } +}
@@ -32,7 +32,7 @@ QAction* action() { return m_action; }
const QAction* action() const { return m_action; } const QMenu* menu() const { return m_menu; } Functions functions() const { return m_functions; } - int key() const { return m_keys; } + int key() const { return m_key; } const QString& visibleName() const { return m_visibleName; } const QString& name() const { return m_name; }@@ -64,6 +64,9 @@ bool operator==(const InputItem& other) const {
return m_name == other.m_name && m_visibleName == other.m_visibleName; } +public slots: + void trigger(bool = true); + signals: void shortcutBound(InputItem*, int shortcut); void buttonBound(InputItem*, int button);@@ -80,7 +83,7 @@
int m_shortcut = 0; int m_button = -1; int m_axis = -1; - int m_keys =-1; + int m_key = -1; GamepadAxisEvent::Direction m_direction = GamepadAxisEvent::NEUTRAL; QList<InputItem*> m_items; InputItem* m_parent;
@@ -136,6 +136,14 @@ InputItem* pmenu = static_cast<InputItem*>(index.parent().internalPointer());
return pmenu->items()[index.row()]; } +InputItem* InputModel::itemAt(const QString& name) { + return m_names[name]; +} + +const InputItem* InputModel::itemAt(const QString& name) const { + return m_names[name]; +} + InputItem* InputModel::itemForMenu(const QMenu* menu) { InputItem* item = m_menus[menu]; if (!item) {@@ -143,12 +151,25 @@ return &m_rootMenu;
} return item; } + const InputItem* InputModel::itemForMenu(const QMenu* menu) const { const InputItem* item = m_menus[menu]; if (!item) { return &m_rootMenu; } return item; +} + +InputItem* InputModel::itemForShortcut(int shortcut) { + return m_shortcuts[shortcut]; +} + +InputItem* InputModel::itemForButton(int button) { + return m_buttons[button]; +} + +InputItem* InputModel::itemForAxis(int axis, GamepadAxisEvent::Direction direction) { + return m_axes[qMakePair(axis, direction)]; } bool InputModel::loadShortcuts(InputItem* item) {@@ -293,6 +314,36 @@ const QMenu* menu = child->menu();
if (menu) { m_menus[menu] = child; } + if (child->shortcut()) { + m_shortcuts[child->shortcut()] = child; + } + if (child->button() >= 0) { + m_buttons[child->button()] = child; + } + if (child->direction() != GamepadAxisEvent::NEUTRAL) { + m_axes[qMakePair(child->axis(), child->direction())] = child; + } m_names[child->name()] = child; connect(child, &InputItem::childAdded, this, &InputModel::itemAdded); + connect(child, &InputItem::shortcutBound, this, &InputModel::rebindShortcut); + connect(child, &InputItem::buttonBound, this, &InputModel::rebindButton); + connect(child, &InputItem::axisBound, this, &InputModel::rebindAxis); +} + +void InputModel::rebindShortcut(InputItem* item, int shortcut) { + if (shortcut) { + m_shortcuts[shortcut] = item; + } +} + +void InputModel::rebindButton(InputItem* item, int button) { + if (button >= 0) { + m_buttons[button] = item; + } +} + +void InputModel::rebindAxis(InputItem* item, int axis, GamepadAxisEvent::Direction direction) { + if (axis != GamepadAxisEvent::NEUTRAL) { + m_axes[qMakePair(axis, direction)] = item; + } }
@@ -37,6 +37,9 @@ constexpr static const char* const AXIS_PROFILE_SECTION = "shortcutProfileAxis.";
private slots: void itemAdded(InputItem* parent, InputItem* child); + void rebindShortcut(InputItem*, int shortcut); + void rebindButton(InputItem*, int button); + void rebindAxis(InputItem*, int axis, GamepadAxisEvent::Direction); public: InputModel(QObject* parent = nullptr);@@ -60,12 +63,13 @@ const InputItem* itemAt(const QString& name) const;
InputItem* itemAt(const QModelIndex& index); const InputItem* itemAt(const QModelIndex& index) const; - InputItem* itemForKey(int key); - const InputItem* itemForKey(int key) const; - InputItem* itemForMenu(const QMenu* menu); const InputItem* itemForMenu(const QMenu* menu) const; + InputItem* itemForShortcut(int shortcut); + InputItem* itemForButton(int button); + InputItem* itemForAxis(int axis, GamepadAxisEvent::Direction); + static int toModifierShortcut(const QString& shortcut); static bool isModifierKey(int key); static int toModifierKey(int key);@@ -84,6 +88,9 @@
InputItem m_rootMenu; QMap<QString, InputItem*> m_names; QMap<const QMenu*, InputItem*> m_menus; + QMap<int, InputItem*> m_shortcuts; + QMap<int, InputItem*> m_buttons; + QMap<QPair<int, GamepadAxisEvent::Direction>, InputItem*> m_axes; ConfigController* m_config; QString m_profileName; const InputProfile* m_profile;
@@ -193,8 +193,6 @@ m_focusCheck.setInterval(200);
m_inputModel->setConfigController(m_config); setupMenu(menuBar()); - - m_inputController.setupCallback(m_controller); } Window::~Window() {@@ -1542,6 +1540,69 @@ m_controller->setAutofire(GBA_KEY_LEFT, true);
}, [this]() { m_controller->setAutofire(GBA_KEY_LEFT, false); }), tr("Autofire Left"), "autofireLeft"); + + QMenu* bindingsMenu = new QMenu(tr("Bindings"), this); + InputItem* bindingsMenuItem = m_inputModel->addItem(bindingsMenu, "bindings"); + + bindingsMenuItem->addItem(qMakePair([this]() { + m_controller->keyPressed(GBA_KEY_A); + }, [this]() { + m_controller->keyReleased(GBA_KEY_A); + }), tr("A"), "keyA"); + + bindingsMenuItem->addItem(qMakePair([this]() { + m_controller->keyPressed(GBA_KEY_B); + }, [this]() { + m_controller->keyReleased(GBA_KEY_B); + }), tr("B"), "keyB"); + + bindingsMenuItem->addItem(qMakePair([this]() { + m_controller->keyPressed(GBA_KEY_START); + }, [this]() { + m_controller->keyReleased(GBA_KEY_START); + }), tr("Start"), "keyStart"); + + bindingsMenuItem->addItem(qMakePair([this]() { + m_controller->keyPressed(GBA_KEY_SELECT); + }, [this]() { + m_controller->keyReleased(GBA_KEY_SELECT); + }), tr("Select"), "keySelect"); + + bindingsMenuItem->addItem(qMakePair([this]() { + m_controller->keyPressed(GBA_KEY_L); + }, [this]() { + m_controller->keyReleased(GBA_KEY_L); + }), tr("L"), "keyL"); + + bindingsMenuItem->addItem(qMakePair([this]() { + m_controller->keyPressed(GBA_KEY_R); + }, [this]() { + m_controller->keyReleased(GBA_KEY_R); + }), tr("R"), "keyR"); + + bindingsMenuItem->addItem(qMakePair([this]() { + m_controller->keyPressed(GBA_KEY_UP); + }, [this]() { + m_controller->keyReleased(GBA_KEY_UP); + }), tr("Up"), "keyUp"); + + bindingsMenuItem->addItem(qMakePair([this]() { + m_controller->keyPressed(GBA_KEY_DOWN); + }, [this]() { + m_controller->keyReleased(GBA_KEY_DOWN); + }), tr("Down"), "keyDown"); + + bindingsMenuItem->addItem(qMakePair([this]() { + m_controller->keyPressed(GBA_KEY_LEFT); + }, [this]() { + m_controller->keyReleased(GBA_KEY_LEFT); + }), tr("Left"), "keyLeft"); + + bindingsMenuItem->addItem(qMakePair([this]() { + m_controller->keyPressed(GBA_KEY_RIGHT); + }, [this]() { + m_controller->keyReleased(GBA_KEY_RIGHT); + }), tr("Right"), "keyRight"); for (QAction* action : m_gameActions) { action->setDisabled(true);