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_hatDirection(GamepadHatEvent::CENTER)
21{
22 setAlignment(Qt::AlignCenter);
23 setFocusPolicy(Qt::ClickFocus);
24 m_lastKey.setSingleShot(true);
25}
26
27void KeyEditor::setValue(int key) {
28 m_key = key;
29 if (m_button) {
30 updateButtonText();
31 } else {
32 if (key < 0) {
33 setText(tr("---"));
34 } else {
35 setText(QKeySequence(key).toString(QKeySequence::NativeText));
36 }
37 }
38 emit valueChanged(key);
39}
40
41void KeyEditor::setValueKey(int key) {
42 m_button = false;
43 setValue(key);
44}
45
46void KeyEditor::setValueButton(int button) {
47 m_button = true;
48 setValue(button);
49}
50
51void KeyEditor::setValueAxis(int axis, int32_t value) {
52 m_button = true;
53 m_axis = axis;
54 m_direction = value < 0 ? GamepadAxisEvent::NEGATIVE : GamepadAxisEvent::POSITIVE;
55 updateButtonText();
56 emit axisChanged(axis, m_direction);
57}
58
59void KeyEditor::setValueHat(int hat, GamepadHatEvent::Direction direction) {
60 m_button = true;
61 m_hat = hat;
62 m_hatDirection = direction;
63 updateButtonText();
64 emit hatChanged(hat, m_hatDirection);
65}
66
67void KeyEditor::clearButton() {
68 m_button = true;
69 setValue(-1);
70}
71
72void KeyEditor::clearAxis() {
73 m_button = true;
74 m_axis = -1;
75 m_direction = GamepadAxisEvent::NEUTRAL;
76 updateButtonText();
77 emit axisChanged(m_axis, m_direction);
78}
79
80void KeyEditor::clearHat() {
81 m_button = true;
82 m_hat = -1;
83 m_hatDirection = GamepadHatEvent::CENTER;
84 updateButtonText();
85 emit hatChanged(m_hat, m_hatDirection);
86}
87
88QSize KeyEditor::sizeHint() const {
89 QSize hint = QLineEdit::sizeHint();
90 QFontMetrics fm(font());
91 hint.setWidth(fm.height() * 4);
92 return hint;
93}
94
95void KeyEditor::keyPressEvent(QKeyEvent* event) {
96 if (!m_button) {
97 if (m_key < 0 || !m_lastKey.isActive()) {
98 m_key = 0;
99 }
100 m_lastKey.start(KEY_TIME);
101 if (m_key) {
102 if (ShortcutController::isModifierKey(m_key)) {
103 switch (event->key()) {
104 case Qt::Key_Shift:
105 setValue(Qt::ShiftModifier);
106 break;
107 case Qt::Key_Control:
108 setValue(Qt::ControlModifier);
109 break;
110 case Qt::Key_Alt:
111 setValue(Qt::AltModifier);
112 break;
113 case Qt::Key_Meta:
114 setValue(Qt::MetaModifier);
115 break;
116 }
117 }
118 if (ShortcutController::isModifierKey(event->key())) {
119 switch (event->key()) {
120 case Qt::Key_Shift:
121 setValue(m_key | Qt::ShiftModifier);
122 break;
123 case Qt::Key_Control:
124 setValue(m_key | Qt::ControlModifier);
125 break;
126 case Qt::Key_Alt:
127 setValue(m_key | Qt::AltModifier);
128 break;
129 case Qt::Key_Meta:
130 setValue(m_key | Qt::MetaModifier);
131 break;
132 }
133 } else {
134 setValue(event->key() | (m_key & (Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier)));
135 }
136 } else {
137 setValue(event->key());
138 }
139 }
140 event->accept();
141}
142
143bool KeyEditor::event(QEvent* event) {
144 if (!m_button) {
145 if (event->type() == QEvent::KeyPress) {
146 QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
147 if (keyEvent->key() != Qt::Key_Tab && keyEvent->key() != Qt::Key_Backtab) {
148 return QWidget::event(event);
149 }
150 if (!(keyEvent->modifiers() & ~Qt::ShiftModifier)) {
151 keyPressEvent(keyEvent);
152 keyEvent->accept();
153 return true;
154 }
155 }
156 } else {
157 if (event->type() == GamepadButtonEvent::Down()) {
158 setValueButton(static_cast<GamepadButtonEvent*>(event)->value());
159 event->accept();
160 return true;
161 }
162 if (event->type() == GamepadHatEvent::Down()) {
163 GamepadHatEvent* ghe = static_cast<GamepadHatEvent*>(event);
164 setValueHat(ghe->hatId(), ghe->direction());
165 event->accept();
166 return true;
167 }
168 if (event->type() == GamepadAxisEvent::Type()) {
169 GamepadAxisEvent* gae = static_cast<GamepadAxisEvent*>(event);
170 if (gae->isNew()) {
171 setValueAxis(gae->axis(), gae->direction());
172 }
173 event->accept();
174 return true;
175 }
176 }
177 return QWidget::event(event);
178}
179
180void KeyEditor::updateButtonText() {
181 QStringList text;
182 if (m_hat >= 0) {
183 switch (m_hatDirection) {
184 case GamepadHatEvent::UP:
185 text.append(QString("↑%0").arg(m_hat));
186 break;
187 case GamepadHatEvent::RIGHT:
188 text.append(QString("→%0").arg(m_hat));
189 break;
190 case GamepadHatEvent::DOWN:
191 text.append(QString("↓%0").arg(m_hat));
192 break;
193 case GamepadHatEvent::LEFT:
194 text.append(QString("←%0").arg(m_hat));
195 break;
196 default:
197 break;
198 }
199 }
200 if (m_key >= 0) {
201 text.append(QString::number(m_key));
202 }
203 if (m_direction != GamepadAxisEvent::NEUTRAL) {
204 text.append((m_direction == GamepadAxisEvent::NEGATIVE ? "-" : "+") + QString::number(m_axis));
205 }
206 if (text.isEmpty()) {
207 setText(tr("---"));
208 } else {
209 setText(text.join("/"));
210 }
211}