all repos — mgba @ e6ea94d2296eae963a48a18d009217a38d92bf9b

mGBA Game Boy Advance Emulator

src/platform/qt/GBAKeyEditor.cpp (view raw)

  1#include "GBAKeyEditor.h"
  2
  3#include <QPaintEvent>
  4#include <QPainter>
  5#include <QPushButton>
  6#include <QTimer>
  7#include <QVBoxLayout>
  8
  9#include "InputController.h"
 10#include "KeyEditor.h"
 11
 12extern "C" {
 13#include "gba-input.h"
 14}
 15
 16using namespace QGBA;
 17
 18const qreal GBAKeyEditor::DPAD_CENTER_X = 0.247;
 19const qreal GBAKeyEditor::DPAD_CENTER_Y = 0.431;
 20const qreal GBAKeyEditor::DPAD_WIDTH = 0.1;
 21const qreal GBAKeyEditor::DPAD_HEIGHT = 0.1;
 22
 23GBAKeyEditor::GBAKeyEditor(InputController* controller, int type, QWidget* parent)
 24	: QWidget(parent)
 25	, m_type(type)
 26	, m_controller(controller)
 27{
 28	setWindowFlags(windowFlags() & ~Qt::WindowFullscreenButtonHint);
 29	setMinimumSize(300, 300);
 30
 31	const GBAInputMap* map = controller->map();
 32
 33	m_keyDU = new KeyEditor(this);
 34	m_keyDD = new KeyEditor(this);
 35	m_keyDL = new KeyEditor(this);
 36	m_keyDR = new KeyEditor(this);
 37	m_keySelect = new KeyEditor(this);
 38	m_keyStart = new KeyEditor(this);
 39	m_keyA = new KeyEditor(this);
 40	m_keyB = new KeyEditor(this);
 41	m_keyL = new KeyEditor(this);
 42	m_keyR = new KeyEditor(this);
 43
 44#ifdef BUILD_SDL
 45	if (type == SDL_BINDING_BUTTON) {
 46		m_keyDU->setNumeric(true);
 47		m_keyDD->setNumeric(true);
 48		m_keyDL->setNumeric(true);
 49		m_keyDR->setNumeric(true);
 50		m_keySelect->setNumeric(true);
 51		m_keyStart->setNumeric(true);
 52		m_keyA->setNumeric(true);
 53		m_keyB->setNumeric(true);
 54		m_keyL->setNumeric(true);
 55		m_keyR->setNumeric(true);
 56	}
 57#endif
 58
 59	m_keyDU->setValue(GBAInputQueryBinding(map, type, GBA_KEY_UP));
 60	m_keyDD->setValue(GBAInputQueryBinding(map, type, GBA_KEY_DOWN));
 61	m_keyDL->setValue(GBAInputQueryBinding(map, type, GBA_KEY_LEFT));
 62	m_keyDR->setValue(GBAInputQueryBinding(map, type, GBA_KEY_RIGHT));
 63	m_keySelect->setValue(GBAInputQueryBinding(map, type, GBA_KEY_SELECT));
 64	m_keyStart->setValue(GBAInputQueryBinding(map, type, GBA_KEY_START));
 65	m_keyA->setValue(GBAInputQueryBinding(map, type, GBA_KEY_A));
 66	m_keyB->setValue(GBAInputQueryBinding(map, type, GBA_KEY_B));
 67	m_keyL->setValue(GBAInputQueryBinding(map, type, GBA_KEY_L));
 68	m_keyR->setValue(GBAInputQueryBinding(map, type, GBA_KEY_R));
 69
 70	connect(m_keyDU, SIGNAL(valueChanged(int)), this, SLOT(setNext()));
 71	connect(m_keyDD, SIGNAL(valueChanged(int)), this, SLOT(setNext()));
 72	connect(m_keyDL, SIGNAL(valueChanged(int)), this, SLOT(setNext()));
 73	connect(m_keyDR, SIGNAL(valueChanged(int)), this, SLOT(setNext()));
 74	connect(m_keySelect, SIGNAL(valueChanged(int)), this, SLOT(setNext()));
 75	connect(m_keyStart, SIGNAL(valueChanged(int)), this, SLOT(setNext()));
 76	connect(m_keyA, SIGNAL(valueChanged(int)), this, SLOT(setNext()));
 77	connect(m_keyB, SIGNAL(valueChanged(int)), this, SLOT(setNext()));
 78	connect(m_keyL, SIGNAL(valueChanged(int)), this, SLOT(setNext()));
 79	connect(m_keyR, SIGNAL(valueChanged(int)), this, SLOT(setNext()));
 80
 81	m_buttons = new QWidget(this);
 82	QVBoxLayout* layout = new QVBoxLayout;
 83	m_buttons->setLayout(layout);
 84
 85	QPushButton* setAll = new QPushButton(tr("Set all"));
 86	connect(setAll, SIGNAL(pressed()), this, SLOT(setAll()));
 87	layout->addWidget(setAll);
 88
 89	QPushButton* save = new QPushButton(tr("Save"));
 90	connect(save, SIGNAL(pressed()), this, SLOT(save()));
 91	layout->addWidget(save);
 92	layout->setSpacing(6);
 93
 94	m_keyOrder = QList<KeyEditor*>{
 95		m_keyDU,
 96		m_keyDR,
 97		m_keyDD,
 98		m_keyDL,
 99		m_keyA,
100		m_keyB,
101		m_keySelect,
102		m_keyStart,
103		m_keyL,
104		m_keyR
105	};
106
107	m_currentKey = m_keyOrder.end();
108
109	m_background.load(":/res/keymap.qpic");
110
111	setAll->setFocus();
112
113#ifdef BUILD_SDL
114	if (type == SDL_BINDING_BUTTON) {
115		m_gamepadTimer = new QTimer(this);
116		connect(m_gamepadTimer, SIGNAL(timeout()), this, SLOT(testGamepad()));
117		m_gamepadTimer->setInterval(100);
118		m_gamepadTimer->start();
119	}
120#endif
121}
122
123void GBAKeyEditor::setAll() {
124	m_currentKey = m_keyOrder.begin();
125	(*m_currentKey)->setFocus();
126}
127
128void GBAKeyEditor::resizeEvent(QResizeEvent* event) {
129	setLocation(m_buttons, 0.5, 0.2);
130	setLocation(m_keyDU, DPAD_CENTER_X, DPAD_CENTER_Y - DPAD_HEIGHT);
131	setLocation(m_keyDD, DPAD_CENTER_X, DPAD_CENTER_Y + DPAD_HEIGHT);
132	setLocation(m_keyDL, DPAD_CENTER_X - DPAD_WIDTH, DPAD_CENTER_Y);
133	setLocation(m_keyDR, DPAD_CENTER_X + DPAD_WIDTH, DPAD_CENTER_Y);
134	setLocation(m_keySelect, 0.415, 0.93);
135	setLocation(m_keyStart, 0.585, 0.93);
136	setLocation(m_keyA, 0.826, 0.451);
137	setLocation(m_keyB, 0.667, 0.490);
138	setLocation(m_keyL, 0.1, 0.1);
139	setLocation(m_keyR, 0.9, 0.1);
140}
141
142void GBAKeyEditor::paintEvent(QPaintEvent* event) {
143	QPainter painter(this);
144	painter.scale(width() / 480.0, height() / 480.0);
145	painter.drawPicture(0, 0, m_background);
146}
147
148void GBAKeyEditor::setNext() {
149	if (m_currentKey == m_keyOrder.end()) {
150		return;
151	}
152
153	if (!(*m_currentKey)->hasFocus()) {
154		m_currentKey = m_keyOrder.end();
155	}
156
157	++m_currentKey;
158	if (m_currentKey != m_keyOrder.end()) {
159		(*m_currentKey)->setFocus();
160	} else {
161		(*(m_currentKey - 1))->clearFocus();
162	}
163}
164
165void GBAKeyEditor::save() {
166	m_controller->bindKey(m_type, m_keyDU->value(), GBA_KEY_UP);
167	m_controller->bindKey(m_type, m_keyDD->value(), GBA_KEY_DOWN);
168	m_controller->bindKey(m_type, m_keyDL->value(), GBA_KEY_LEFT);
169	m_controller->bindKey(m_type, m_keyDR->value(), GBA_KEY_RIGHT);
170	m_controller->bindKey(m_type, m_keySelect->value(), GBA_KEY_SELECT);
171	m_controller->bindKey(m_type, m_keyStart->value(), GBA_KEY_START);
172	m_controller->bindKey(m_type, m_keyA->value(), GBA_KEY_A);
173	m_controller->bindKey(m_type, m_keyB->value(), GBA_KEY_B);
174	m_controller->bindKey(m_type, m_keyL->value(), GBA_KEY_L);
175	m_controller->bindKey(m_type, m_keyR->value(), GBA_KEY_R);
176	m_controller->saveConfiguration(m_type);
177}
178
179#ifdef BUILD_SDL
180void GBAKeyEditor::testGamepad() {
181	QSet<int> activeKeys = m_controller->activeGamepadButtons();
182	if (activeKeys.empty()) {
183		return;
184	}
185	for (KeyEditor* key : m_keyOrder) {
186		if (!key->hasFocus()) {
187			continue;
188		}
189		key->setValue(*activeKeys.begin());
190	}
191}
192#endif
193
194void GBAKeyEditor::setLocation(QWidget* widget, qreal x, qreal y) {
195	QSize s = size();
196	QSize hint = widget->sizeHint();
197	widget->setGeometry(s.width() * x - hint.width() / 2.0, s.height() * y - hint.height() / 2.0, hint.width(), hint.height());
198}