all repos — mgba @ 67905d281bfecbb06f51f2ca5ac939df378734a5

mGBA Game Boy Advance Emulator

src/platform/qt/KeyEditor.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 "KeyEditor.h"
  7
  8#include "GamepadAxisEvent.h"
  9#include "GamepadButtonEvent.h"
 10#include "ShortcutController.h"
 11
 12#include <QFontMetrics>
 13#include <QKeyEvent>
 14
 15using namespace QGBA;
 16
 17KeyEditor::KeyEditor(QWidget* parent)
 18	: QLineEdit(parent)
 19	, m_direction(GamepadAxisEvent::NEUTRAL)
 20	, m_key(-1)
 21	, m_axis(-1)
 22	, m_button(false)
 23{
 24	setAlignment(Qt::AlignCenter);
 25	setFocusPolicy(Qt::ClickFocus);
 26	m_lastKey.setSingleShot(true);
 27}
 28
 29void KeyEditor::setValue(int key) {
 30	m_key = key;
 31	if (m_button) {
 32		updateButtonText();
 33	} else {
 34		if (key < 0) {
 35			setText(tr("---"));
 36		} else {
 37			setText(QKeySequence(key).toString(QKeySequence::NativeText));
 38		}
 39	}
 40	emit valueChanged(key);
 41}
 42
 43void KeyEditor::setValueKey(int key) {
 44	m_button = false;
 45	setValue(key);
 46}
 47
 48void KeyEditor::setValueButton(int button) {
 49	m_button = true;
 50	setValue(button);
 51}
 52
 53void KeyEditor::setValueAxis(int axis, int32_t value) {
 54	m_button = true;
 55	m_axis = axis;
 56	m_direction = value < 0 ? GamepadAxisEvent::NEGATIVE : GamepadAxisEvent::POSITIVE;
 57	updateButtonText();
 58	emit axisChanged(axis, m_direction);
 59}
 60
 61void KeyEditor::clearButton() {
 62	m_button = true;
 63	setValue(-1);
 64}
 65
 66void KeyEditor::clearAxis() {
 67	m_button = true;
 68	m_axis = -1;
 69	m_direction = GamepadAxisEvent::NEUTRAL;
 70	updateButtonText();
 71	emit axisChanged(m_axis, m_direction);
 72}
 73
 74QSize KeyEditor::sizeHint() const {
 75	QSize hint = QLineEdit::sizeHint();
 76	QFontMetrics fm(font());
 77	hint.setWidth(fm.height() * 3);
 78	return hint;
 79}
 80
 81void KeyEditor::keyPressEvent(QKeyEvent* event) {
 82	if (!m_button) {
 83		if (m_key < 0 || !m_lastKey.isActive()) {
 84			m_key = 0;
 85		}
 86		m_lastKey.start(KEY_TIME);
 87		if (m_key) {
 88			if (ShortcutController::isModifierKey(m_key)) {
 89				switch (event->key()) {
 90				case Qt::Key_Shift:
 91					setValue(Qt::ShiftModifier);
 92					break;
 93				case Qt::Key_Control:
 94					setValue(Qt::ControlModifier);
 95					break;
 96				case Qt::Key_Alt:
 97					setValue(Qt::AltModifier);
 98					break;
 99				case Qt::Key_Meta:
100					setValue(Qt::MetaModifier);
101					break;
102				}
103			}
104			if (ShortcutController::isModifierKey(event->key())) {
105				switch (event->key()) {
106				case Qt::Key_Shift:
107					setValue(m_key | Qt::ShiftModifier);
108					break;
109				case Qt::Key_Control:
110					setValue(m_key | Qt::ControlModifier);
111					break;
112				case Qt::Key_Alt:
113					setValue(m_key | Qt::AltModifier);
114					break;
115				case Qt::Key_Meta:
116					setValue(m_key | Qt::MetaModifier);
117					break;
118				}
119			} else {
120				setValue(event->key() | (m_key & (Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier)));
121			}
122		} else {
123			setValue(event->key());
124		}
125	}
126	event->accept();
127}
128
129bool KeyEditor::event(QEvent* event) {
130	if (!m_button) {
131		if (event->type() == QEvent::KeyPress) {
132			QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
133			if (keyEvent->key() != Qt::Key_Tab && keyEvent->key() != Qt::Key_Backtab) {
134				return QWidget::event(event);
135			}
136			if (!(keyEvent->modifiers() & ~Qt::ShiftModifier)) {
137				keyPressEvent(keyEvent);
138				keyEvent->accept();
139				return true;
140			}
141		}
142	} else {
143		if (event->type() == GamepadButtonEvent::Down()) {
144			setValueButton(static_cast<GamepadButtonEvent*>(event)->value());
145			event->accept();
146			return true;
147		}
148		if (event->type() == GamepadAxisEvent::Type()) {
149			GamepadAxisEvent* gae = static_cast<GamepadAxisEvent*>(event);
150			if (gae->isNew()) {
151				setValueAxis(gae->axis(), gae->direction());
152			}
153			event->accept();
154			return true;
155		}
156	}
157	return QWidget::event(event);
158}
159
160void KeyEditor::updateButtonText() {
161	QStringList text;
162	if (m_key >= 0) {
163		text.append(QString::number(m_key));
164	}
165	if (m_direction != GamepadAxisEvent::NEUTRAL) {
166		text.append((m_direction == GamepadAxisEvent::NEGATIVE ? "-" : "+") + QString::number(m_axis));
167	}
168	if (text.isEmpty()) {
169		setText(tr("---"));
170	} else {
171		setText(text.join("/"));
172	}
173}