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}