mirror of https://github.com/mgba-emu/mgba.git
Qt: Add GamepadButtonEvent and remove signal associated; use this for button controls in emulator
This commit is contained in:
parent
53c586044d
commit
33c4b17941
|
@ -44,6 +44,7 @@ set(SOURCE_FILES
|
|||
GIFView.cpp
|
||||
GameController.cpp
|
||||
GamePakView.cpp
|
||||
GamepadButtonEvent.cpp
|
||||
InputController.cpp
|
||||
KeyEditor.cpp
|
||||
LoadSaveState.cpp
|
||||
|
|
|
@ -112,7 +112,6 @@ GBAKeyEditor::GBAKeyEditor(InputController* controller, int type, QWidget* paren
|
|||
|
||||
#ifdef BUILD_SDL
|
||||
if (type == SDL_BINDING_BUTTON) {
|
||||
connect(m_controller, SIGNAL(buttonPressed(int)), this, SLOT(setButton(int)));
|
||||
connect(m_controller, SIGNAL(axisChanged(int, int32_t)), this, SLOT(setAxisValue(int, int32_t)));
|
||||
}
|
||||
#endif
|
||||
|
@ -237,14 +236,6 @@ void GBAKeyEditor::setAxisValue(int axis, int32_t value) {
|
|||
KeyEditor* focused = *m_currentKey;
|
||||
focused->setValueAxis(axis, value);
|
||||
}
|
||||
|
||||
void GBAKeyEditor::setButton(int button) {
|
||||
if (!findFocus()) {
|
||||
return;
|
||||
}
|
||||
KeyEditor* focused = *m_currentKey;
|
||||
focused->setValueButton(button);
|
||||
}
|
||||
#endif
|
||||
|
||||
KeyEditor* GBAKeyEditor::keyById(GBAKey key) {
|
||||
|
|
|
@ -40,7 +40,6 @@ private slots:
|
|||
void save();
|
||||
#ifdef BUILD_SDL
|
||||
void setAxisValue(int axis, int32_t value);
|
||||
void setButton(int button);
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/* Copyright (c) 2013-2015 Jeffrey Pfau
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include "GamepadButtonEvent.h"
|
||||
|
||||
#include "InputController.h"
|
||||
|
||||
using namespace QGBA;
|
||||
|
||||
QEvent::Type GamepadButtonEvent::s_downType = QEvent::None;
|
||||
QEvent::Type GamepadButtonEvent::s_upType = QEvent::None;
|
||||
|
||||
GamepadButtonEvent::GamepadButtonEvent(QEvent::Type type, int button, InputController* controller)
|
||||
: QEvent(type)
|
||||
, m_button(button)
|
||||
, m_controller(controller)
|
||||
, m_key(GBA_KEY_NONE)
|
||||
{
|
||||
ignore();
|
||||
#ifdef BUILD_SDL
|
||||
if (controller) {
|
||||
m_key = GBAInputMapKey(controller->map(), SDL_BINDING_BUTTON, button);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
QEvent::Type GamepadButtonEvent::Down() {
|
||||
if (s_downType == None) {
|
||||
s_downType = static_cast<Type>(registerEventType());
|
||||
}
|
||||
return s_downType;
|
||||
}
|
||||
|
||||
QEvent::Type GamepadButtonEvent::Up() {
|
||||
if (s_upType == None) {
|
||||
s_upType = static_cast<Type>(registerEventType());
|
||||
}
|
||||
return s_upType;
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/* Copyright (c) 2013-2015 Jeffrey Pfau
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#ifndef QGBA_GAMEPAD_BUTTON_EVENT
|
||||
#define QGBA_GAMEPAD_BUTTON_EVENT
|
||||
|
||||
#include <QEvent>
|
||||
|
||||
extern "C" {
|
||||
#include "gba-input.h"
|
||||
}
|
||||
|
||||
namespace QGBA {
|
||||
|
||||
class InputController;
|
||||
|
||||
class GamepadButtonEvent : public QEvent {
|
||||
public:
|
||||
GamepadButtonEvent(Type type, int button, InputController* controller = nullptr);
|
||||
|
||||
int value() const { return m_button; }
|
||||
GBAKey gbaKey() const { return m_key; }
|
||||
|
||||
static Type Down();
|
||||
static Type Up();
|
||||
|
||||
private:
|
||||
static Type s_downType;
|
||||
static Type s_upType;
|
||||
|
||||
int m_button;
|
||||
InputController* m_controller;
|
||||
GBAKey m_key;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -6,8 +6,11 @@
|
|||
#include "InputController.h"
|
||||
|
||||
#include "ConfigController.h"
|
||||
#include "GamepadButtonEvent.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QTimer>
|
||||
#include <QWidget>
|
||||
|
||||
extern "C" {
|
||||
#include "util/configuration.h"
|
||||
|
@ -91,6 +94,9 @@ int InputController::testSDLEvents() {
|
|||
if (key == GBA_KEY_NONE) {
|
||||
continue;
|
||||
}
|
||||
if (hasPendingEvent(key)) {
|
||||
continue;
|
||||
}
|
||||
if (SDL_JoystickGetButton(joystick, i)) {
|
||||
activeButtons |= 1 << key;
|
||||
}
|
||||
|
@ -191,10 +197,29 @@ void InputController::testGamepad() {
|
|||
activeButtons.subtract(oldButtons);
|
||||
oldButtons.subtract(m_activeButtons);
|
||||
for (int button : activeButtons) {
|
||||
emit buttonPressed(button);
|
||||
GamepadButtonEvent* event = new GamepadButtonEvent(GamepadButtonEvent::Down(), button, this);
|
||||
postPendingEvent(event->gbaKey());
|
||||
QApplication::sendEvent(QApplication::focusWidget(), event);
|
||||
if (!event->isAccepted()) {
|
||||
clearPendingEvent(event->gbaKey());
|
||||
}
|
||||
}
|
||||
for (int button : oldButtons) {
|
||||
emit buttonReleased(button);
|
||||
GamepadButtonEvent* event = new GamepadButtonEvent(GamepadButtonEvent::Up(), button, this);
|
||||
clearPendingEvent(event->gbaKey());
|
||||
QApplication::sendEvent(QApplication::focusWidget(), event);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void InputController::postPendingEvent(GBAKey key) {
|
||||
m_pendingEvents.insert(key);
|
||||
}
|
||||
|
||||
void InputController::clearPendingEvent(GBAKey key) {
|
||||
m_pendingEvents.remove(key);
|
||||
}
|
||||
|
||||
bool InputController::hasPendingEvent(GBAKey key) const {
|
||||
return m_pendingEvents.contains(key);
|
||||
}
|
||||
|
|
|
@ -59,13 +59,15 @@ public:
|
|||
|
||||
signals:
|
||||
void axisChanged(int axis, int32_t value);
|
||||
void buttonPressed(int button);
|
||||
void buttonReleased(int button);
|
||||
|
||||
public slots:
|
||||
void testGamepad();
|
||||
|
||||
private:
|
||||
void postPendingEvent(GBAKey);
|
||||
void clearPendingEvent(GBAKey);
|
||||
bool hasPendingEvent(GBAKey) const;
|
||||
|
||||
GBAInputMap m_inputMap;
|
||||
ConfigController* m_config;
|
||||
|
||||
|
@ -76,6 +78,8 @@ private:
|
|||
QSet<int> m_activeButtons;
|
||||
QSet<QPair<int, int32_t>> m_activeAxes;
|
||||
QTimer* m_gamepadTimer;
|
||||
|
||||
QSet<GBAKey> m_pendingEvents;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include "KeyEditor.h"
|
||||
|
||||
#include "GamepadButtonEvent.h"
|
||||
|
||||
#include <QKeyEvent>
|
||||
|
||||
using namespace QGBA;
|
||||
|
@ -56,3 +58,15 @@ void KeyEditor::keyPressEvent(QKeyEvent* event) {
|
|||
}
|
||||
event->accept();
|
||||
}
|
||||
|
||||
bool KeyEditor::event(QEvent* event) {
|
||||
if (!m_button) {
|
||||
return QWidget::event(event);
|
||||
}
|
||||
if (event->type() == GamepadButtonEvent::Down()) {
|
||||
setValueButton(static_cast<GamepadButtonEvent*>(event)->value());
|
||||
event->accept();
|
||||
return true;
|
||||
}
|
||||
return QWidget::event(event);
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ signals:
|
|||
|
||||
protected:
|
||||
virtual void keyPressEvent(QKeyEvent* event) override;
|
||||
virtual bool event(QEvent* event) override;
|
||||
|
||||
private:
|
||||
int m_key;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "LoadSaveState.h"
|
||||
|
||||
#include "GameController.h"
|
||||
#include "GamepadButtonEvent.h"
|
||||
#include "VFileDevice.h"
|
||||
|
||||
#include <QKeyEvent>
|
||||
|
@ -104,6 +105,40 @@ bool LoadSaveState::eventFilter(QObject* object, QEvent* event) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (event->type() == GamepadButtonEvent::Down()) {
|
||||
int column = m_currentFocus % 3;
|
||||
int row = m_currentFocus - column;
|
||||
switch (static_cast<GamepadButtonEvent*>(event)->gbaKey()) {
|
||||
case GBA_KEY_UP:
|
||||
row += 6;
|
||||
break;
|
||||
case GBA_KEY_DOWN:
|
||||
row += 3;
|
||||
break;
|
||||
case GBA_KEY_LEFT:
|
||||
column += 2;
|
||||
break;
|
||||
case GBA_KEY_RIGHT:
|
||||
column += 1;
|
||||
break;
|
||||
case GBA_KEY_B:
|
||||
close();
|
||||
break;
|
||||
case GBA_KEY_A:
|
||||
case GBA_KEY_START:
|
||||
event->accept();
|
||||
triggerState(m_currentFocus + 1);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
column %= 3;
|
||||
row %= 9;
|
||||
m_currentFocus = column + row;
|
||||
m_slots[m_currentFocus]->setFocus();
|
||||
event->accept();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
namespace QGBA {
|
||||
|
||||
class GameController;
|
||||
class InputController;
|
||||
class SavestateButton;
|
||||
|
||||
enum class LoadSave {
|
||||
|
@ -28,6 +29,7 @@ public:
|
|||
|
||||
LoadSaveState(GameController* controller, QWidget* parent = nullptr);
|
||||
|
||||
void setInputController(InputController* controller);
|
||||
void setMode(LoadSave mode);
|
||||
|
||||
signals:
|
||||
|
@ -45,6 +47,7 @@ private:
|
|||
|
||||
Ui::LoadSaveState m_ui;
|
||||
GameController* m_controller;
|
||||
InputController* m_inputController;
|
||||
SavestateButton* m_slots[NUM_SLOTS];
|
||||
LoadSave m_mode;
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include "ShortcutController.h"
|
||||
|
||||
#include "GamepadButtonEvent.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QMenu>
|
||||
|
||||
|
@ -166,16 +168,20 @@ void ShortcutController::updateButton(const QModelIndex& index, int button) {
|
|||
emit dataChanged(createIndex(index.row(), 0, index.internalId()), createIndex(index.row(), 2, index.internalId()));
|
||||
}
|
||||
|
||||
void ShortcutController::pressButton(int button) {
|
||||
auto item = m_buttons.find(button);
|
||||
if (item == m_buttons.end()) {
|
||||
return;
|
||||
bool ShortcutController::eventFilter(QObject*, QEvent* event) {
|
||||
if (event->type() == GamepadButtonEvent::Down()) {
|
||||
auto item = m_buttons.find(static_cast<GamepadButtonEvent*>(event)->value());
|
||||
if (item == m_buttons.end()) {
|
||||
return false;
|
||||
}
|
||||
QAction* action = item.value()->action();
|
||||
if (action->isEnabled()) {
|
||||
action->trigger();
|
||||
}
|
||||
event->accept();
|
||||
return true;
|
||||
}
|
||||
QAction* action = item.value()->action();
|
||||
if (!action->isEnabled()) {
|
||||
return;
|
||||
}
|
||||
action->trigger();
|
||||
return false;
|
||||
}
|
||||
|
||||
ShortcutController::ShortcutItem::ShortcutItem(QAction* action, const QString& name)
|
||||
|
|
|
@ -36,8 +36,8 @@ public:
|
|||
void updateKey(const QModelIndex& index, const QKeySequence& keySequence);
|
||||
void updateButton(const QModelIndex& index, int button);
|
||||
|
||||
private slots:
|
||||
void pressButton(int button);
|
||||
protected:
|
||||
bool eventFilter(QObject*, QEvent*) override;
|
||||
|
||||
private:
|
||||
class ShortcutItem {
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include "ShortcutView.h"
|
||||
|
||||
#include "GamepadButtonEvent.h"
|
||||
#include "ShortcutController.h"
|
||||
|
||||
using namespace QGBA;
|
||||
|
@ -15,10 +16,11 @@ ShortcutView::ShortcutView(QWidget* parent)
|
|||
, m_inputController(nullptr)
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
m_ui.keyEdit->setValueButton(-1);
|
||||
|
||||
connect(m_ui.keySequenceEdit, SIGNAL(editingFinished()), this, SLOT(updateKey()));
|
||||
connect(m_ui.keyEdit, SIGNAL(valueChanged(int)), this, SLOT(updateButton(int)));
|
||||
connect(m_ui.shortcutTable, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(loadKey(const QModelIndex&)));
|
||||
connect(m_ui.shortcutTable, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(load(const QModelIndex&)));
|
||||
}
|
||||
|
||||
void ShortcutView::setController(ShortcutController* controller) {
|
||||
|
@ -28,11 +30,19 @@ void ShortcutView::setController(ShortcutController* controller) {
|
|||
|
||||
void ShortcutView::setInputController(InputController* controller) {
|
||||
m_inputController = controller;
|
||||
connect(controller, SIGNAL(buttonPressed(int)), m_ui.keyEdit, SLOT(setValueButton(int)));
|
||||
connect(controller, SIGNAL(axisChanged(int, int32_t)), m_ui.keyEdit, SLOT(setValueAxis(int, int32_t)));
|
||||
}
|
||||
|
||||
void ShortcutView::loadKey(const QModelIndex& index) {
|
||||
bool ShortcutView::event(QEvent* event) {
|
||||
if (event->type() == GamepadButtonEvent::Down()) {
|
||||
updateButton(static_cast<GamepadButtonEvent*>(event)->value());
|
||||
event->accept();
|
||||
return true;
|
||||
}
|
||||
return QWidget::event(event);
|
||||
}
|
||||
|
||||
void ShortcutView::load(const QModelIndex& index) {
|
||||
if (!m_controller) {
|
||||
return;
|
||||
}
|
||||
|
@ -40,8 +50,11 @@ void ShortcutView::loadKey(const QModelIndex& index) {
|
|||
if (!action) {
|
||||
return;
|
||||
}
|
||||
m_ui.keySequenceEdit->setFocus();
|
||||
m_ui.keySequenceEdit->setKeySequence(action->shortcut());
|
||||
if (m_ui.gamepadButton->isChecked()) {
|
||||
loadButton();
|
||||
} else {
|
||||
loadKey(action);
|
||||
}
|
||||
}
|
||||
|
||||
void ShortcutView::updateKey() {
|
||||
|
@ -59,3 +72,12 @@ void ShortcutView::updateButton(int button) {
|
|||
m_controller->updateButton(m_ui.shortcutTable->selectionModel()->currentIndex(), button);
|
||||
|
||||
}
|
||||
void ShortcutView::loadKey(const QAction* action) {
|
||||
m_ui.keySequenceEdit->setFocus();
|
||||
m_ui.keySequenceEdit->setKeySequence(action->shortcut());
|
||||
}
|
||||
|
||||
void ShortcutView::loadButton() {
|
||||
m_ui.keyEdit->setFocus();
|
||||
m_ui.keyEdit->setValueButton(-1); // TODO: Real value
|
||||
}
|
||||
|
|
|
@ -25,12 +25,18 @@ public:
|
|||
void setController(ShortcutController* controller);
|
||||
void setInputController(InputController* controller);
|
||||
|
||||
protected:
|
||||
virtual bool event(QEvent* event) override;
|
||||
|
||||
private slots:
|
||||
void loadKey(const QModelIndex&);
|
||||
void load(const QModelIndex&);
|
||||
void updateKey();
|
||||
void updateButton(int button);
|
||||
|
||||
private:
|
||||
void loadKey(const QAction*);
|
||||
void loadButton();
|
||||
|
||||
Ui::ShortcutView m_ui;
|
||||
|
||||
ShortcutController* m_controller;
|
||||
|
|
|
@ -93,8 +93,6 @@ Window::Window(ConfigController* config, QWidget* parent)
|
|||
connect(this, SIGNAL(fpsTargetChanged(float)), m_controller, SLOT(setFPSTarget(float)));
|
||||
connect(&m_fpsTimer, SIGNAL(timeout()), this, SLOT(showFPS()));
|
||||
|
||||
connect(&m_inputController, SIGNAL(buttonPressed(int)), m_shortcutController, SLOT(pressButton(int)));
|
||||
|
||||
m_logView->setLevels(GBA_LOG_WARN | GBA_LOG_ERROR | GBA_LOG_FATAL);
|
||||
m_fpsTimer.setInterval(FPS_TIMER_INTERVAL);
|
||||
|
||||
|
@ -431,6 +429,7 @@ void Window::setupMenu(QMenuBar* menubar) {
|
|||
menubar->clear();
|
||||
QMenu* fileMenu = menubar->addMenu(tr("&File"));
|
||||
m_shortcutController->addMenu(fileMenu);
|
||||
installEventFilter(m_shortcutController);
|
||||
addControlledAction(fileMenu, fileMenu->addAction(tr("Load &ROM..."), this, SLOT(selectROM()), QKeySequence::Open), "loadROM");
|
||||
addControlledAction(fileMenu, fileMenu->addAction(tr("Load &BIOS..."), this, SLOT(selectBIOS())), "loadBIOS");
|
||||
addControlledAction(fileMenu, fileMenu->addAction(tr("Load &patch..."), this, SLOT(selectPatch())), "loadPatch");
|
||||
|
|
Loading…
Reference in New Issue