all repos — mgba @ 1c1fbfe163964cb9a6744b134bda71464dd232f4

mGBA Game Boy Advance Emulator

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

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