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}