all repos — mgba @ b9c942546475eb971a142fc9ec905beeb7a93815

mGBA Game Boy Advance Emulator

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

  1/* Copyright (c) 2013-2015 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 "ShortcutView.h"
  7
  8#include "GamepadButtonEvent.h"
  9#include "InputController.h"
 10#include "ShortcutController.h"
 11
 12#include <QKeyEvent>
 13
 14using namespace QGBA;
 15
 16ShortcutView::ShortcutView(QWidget* parent)
 17	: QWidget(parent)
 18	, m_controller(nullptr)
 19	, m_input(nullptr)
 20{
 21	m_ui.setupUi(this);
 22	m_ui.keyEdit->setValueButton(-1);
 23	m_ui.keySequenceEdit->installEventFilter(this);
 24
 25	connect(m_ui.keySequenceEdit, SIGNAL(keySequenceChanged(const QKeySequence&)), this, SLOT(updateKey(const QKeySequence&)));
 26	connect(m_ui.keyEdit, SIGNAL(valueChanged(int)), this, SLOT(updateButton(int)));
 27	connect(m_ui.keyEdit, SIGNAL(axisChanged(int, int)), this, SLOT(updateAxis(int, int)));
 28	connect(m_ui.shortcutTable, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(load(const QModelIndex&)));
 29	connect(m_ui.clearButton, SIGNAL(clicked()), this, SLOT(clear()));
 30}
 31
 32void ShortcutView::setController(ShortcutController* controller) {
 33	m_controller = controller;
 34	m_ui.shortcutTable->setModel(controller);
 35}
 36
 37void ShortcutView::setInputController(InputController* controller) {
 38	if (m_input) {
 39		m_input->releaseFocus(this);
 40	}
 41	m_input = controller;
 42	m_input->stealFocus(this);
 43}
 44
 45bool ShortcutView::eventFilter(QObject*, QEvent* event) {
 46	if (event->type() == QEvent::KeyPress) {
 47		QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
 48		if (keyEvent->key() != Qt::Key_Tab && keyEvent->key() != Qt::Key_Backtab) {
 49			return false;
 50		}
 51		if (!(keyEvent->modifiers() & ~Qt::ShiftModifier)) {
 52			m_ui.keySequenceEdit->setKeySequence(ShortcutController::keyEventToSequence(keyEvent));
 53			keyEvent->accept();
 54			return true;
 55		}
 56	}
 57	return false;
 58}
 59
 60void ShortcutView::load(const QModelIndex& index) {
 61	if (!m_controller) {
 62		return;
 63	}
 64	if (m_controller->isMenuAt(index)) {
 65		return;
 66	}
 67	QKeySequence sequence = m_controller->shortcutAt(index);
 68	if (index.column() == 1) {
 69		m_ui.keyboardButton->click();
 70	} else if (index.column() == 2) {
 71		m_ui.gamepadButton->click();
 72	}
 73	if (m_ui.gamepadButton->isChecked()) {
 74		bool blockSignals = m_ui.keyEdit->blockSignals(true);
 75		m_ui.keyEdit->setFocus();
 76		m_ui.keyEdit->setValueButton(-1); // There are no default bindings
 77		m_ui.keyEdit->blockSignals(blockSignals);
 78	} else {
 79		bool blockSignals = m_ui.keySequenceEdit->blockSignals(true);
 80		m_ui.keySequenceEdit->setFocus();
 81		m_ui.keySequenceEdit->setKeySequence(sequence);
 82		m_ui.keySequenceEdit->blockSignals(blockSignals);
 83	}
 84}
 85
 86void ShortcutView::clear() {
 87	if (!m_controller) {
 88		return;
 89	}
 90	QModelIndex index = m_ui.shortcutTable->selectionModel()->currentIndex();
 91	if (m_controller->isMenuAt(index)) {
 92		return;
 93	}
 94	if (m_ui.gamepadButton->isChecked()) {
 95		m_controller->clearButton(index);
 96		m_ui.keyEdit->setValueButton(-1);
 97	} else {
 98		m_controller->clearKey(index);
 99		m_ui.keySequenceEdit->setKeySequence(QKeySequence());
100	}
101}
102
103void ShortcutView::updateKey(const QKeySequence& shortcut) {
104	if (!m_controller || m_controller->isMenuAt(m_ui.shortcutTable->selectionModel()->currentIndex())) {
105		return;
106	}
107	m_controller->updateKey(m_ui.shortcutTable->selectionModel()->currentIndex(), shortcut);
108}
109
110void ShortcutView::updateButton(int button) {
111	if (!m_controller || m_controller->isMenuAt(m_ui.shortcutTable->selectionModel()->currentIndex())) {
112		return;
113	}
114	m_controller->updateButton(m_ui.shortcutTable->selectionModel()->currentIndex(), button);
115}
116
117void ShortcutView::updateAxis(int axis, int direction) {
118	if (!m_controller || m_controller->isMenuAt(m_ui.shortcutTable->selectionModel()->currentIndex())) {
119		return;
120	}
121	m_controller->updateAxis(m_ui.shortcutTable->selectionModel()->currentIndex(), axis,
122	                         static_cast<GamepadAxisEvent::Direction>(direction));
123}
124
125void ShortcutView::closeEvent(QCloseEvent*) {
126	if (m_input) {
127		m_input->releaseFocus(this);
128	}
129}
130
131bool ShortcutView::event(QEvent* event) {
132	if (m_input) {
133		if (event->type() == QEvent::WindowActivate) {
134			m_input->stealFocus(this);
135		} else if (event->type() == QEvent::WindowDeactivate) {
136			m_input->releaseFocus(this);
137		}
138	}
139	return QWidget::event(event);
140}