diff options
Diffstat (limited to 'src/citra_qt/configure_input.cpp')
| -rw-r--r-- | src/citra_qt/configure_input.cpp | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/src/citra_qt/configure_input.cpp b/src/citra_qt/configure_input.cpp new file mode 100644 index 000000000..9c7a67174 --- /dev/null +++ b/src/citra_qt/configure_input.cpp | |||
| @@ -0,0 +1,149 @@ | |||
| 1 | // Copyright 2016 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <memory> | ||
| 6 | #include <utility> | ||
| 7 | #include <QTimer> | ||
| 8 | |||
| 9 | #include "citra_qt/configure_input.h" | ||
| 10 | |||
| 11 | ConfigureInput::ConfigureInput(QWidget* parent) : QWidget(parent), ui(std::make_unique<Ui::ConfigureInput>()) { | ||
| 12 | ui->setupUi(this); | ||
| 13 | |||
| 14 | // Initialize mapping of input enum to UI button. | ||
| 15 | input_mapping = { | ||
| 16 | { std::make_pair(Settings::NativeInput::Values::A, ui->buttonA) }, | ||
| 17 | { std::make_pair(Settings::NativeInput::Values::B, ui->buttonB) }, | ||
| 18 | { std::make_pair(Settings::NativeInput::Values::X, ui->buttonX) }, | ||
| 19 | { std::make_pair(Settings::NativeInput::Values::Y, ui->buttonY) }, | ||
| 20 | { std::make_pair(Settings::NativeInput::Values::L, ui->buttonL) }, | ||
| 21 | { std::make_pair(Settings::NativeInput::Values::R, ui->buttonR) }, | ||
| 22 | { std::make_pair(Settings::NativeInput::Values::ZL, ui->buttonZL) }, | ||
| 23 | { std::make_pair(Settings::NativeInput::Values::ZR, ui->buttonZR) }, | ||
| 24 | { std::make_pair(Settings::NativeInput::Values::START, ui->buttonStart) }, | ||
| 25 | { std::make_pair(Settings::NativeInput::Values::SELECT, ui->buttonSelect) }, | ||
| 26 | { std::make_pair(Settings::NativeInput::Values::HOME, ui->buttonHome) }, | ||
| 27 | { std::make_pair(Settings::NativeInput::Values::DUP, ui->buttonDpadUp) }, | ||
| 28 | { std::make_pair(Settings::NativeInput::Values::DDOWN, ui->buttonDpadDown) }, | ||
| 29 | { std::make_pair(Settings::NativeInput::Values::DLEFT, ui->buttonDpadLeft) }, | ||
| 30 | { std::make_pair(Settings::NativeInput::Values::DRIGHT, ui->buttonDpadRight) }, | ||
| 31 | { std::make_pair(Settings::NativeInput::Values::CUP, ui->buttonCStickUp) }, | ||
| 32 | { std::make_pair(Settings::NativeInput::Values::CDOWN, ui->buttonCStickDown) }, | ||
| 33 | { std::make_pair(Settings::NativeInput::Values::CLEFT, ui->buttonCStickLeft) }, | ||
| 34 | { std::make_pair(Settings::NativeInput::Values::CRIGHT, ui->buttonCStickRight) }, | ||
| 35 | { std::make_pair(Settings::NativeInput::Values::CIRCLE_UP, ui->buttonCircleUp) }, | ||
| 36 | { std::make_pair(Settings::NativeInput::Values::CIRCLE_DOWN, ui->buttonCircleDown) }, | ||
| 37 | { std::make_pair(Settings::NativeInput::Values::CIRCLE_LEFT, ui->buttonCircleLeft) }, | ||
| 38 | { std::make_pair(Settings::NativeInput::Values::CIRCLE_RIGHT, ui->buttonCircleRight) }, | ||
| 39 | { std::make_pair(Settings::NativeInput::Values::CIRCLE_MODIFIER, ui->buttonCircleMod) }, | ||
| 40 | }; | ||
| 41 | |||
| 42 | // Attach handle click method to each button click. | ||
| 43 | for (const auto& entry : input_mapping) { | ||
| 44 | connect(entry.second, SIGNAL(released()), this, SLOT(handleClick())); | ||
| 45 | } | ||
| 46 | connect(ui->buttonRestoreDefaults, SIGNAL(released()), this, SLOT(restoreDefaults())); | ||
| 47 | setFocusPolicy(Qt::ClickFocus); | ||
| 48 | timer = new QTimer(this); | ||
| 49 | timer->setSingleShot(true); | ||
| 50 | connect(timer, &QTimer::timeout, this, [&]() { key_pressed = Qt::Key_Escape; setKey(); }); | ||
| 51 | this->setConfiguration(); | ||
| 52 | } | ||
| 53 | |||
| 54 | void ConfigureInput::handleClick() { | ||
| 55 | QPushButton* sender = qobject_cast<QPushButton*>(QObject::sender()); | ||
| 56 | previous_mapping = sender->text(); | ||
| 57 | sender->setText(tr("[waiting]")); | ||
| 58 | sender->setFocus(); | ||
| 59 | grabKeyboard(); | ||
| 60 | grabMouse(); | ||
| 61 | changing_button = sender; | ||
| 62 | timer->start(5000); //Cancel after 5 seconds | ||
| 63 | } | ||
| 64 | |||
| 65 | void ConfigureInput::applyConfiguration() { | ||
| 66 | for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) { | ||
| 67 | int value = getKeyValue(input_mapping[Settings::NativeInput::Values(i)]->text()); | ||
| 68 | Settings::values.input_mappings[Settings::NativeInput::All[i]] = value; | ||
| 69 | } | ||
| 70 | Settings::Apply(); | ||
| 71 | } | ||
| 72 | |||
| 73 | void ConfigureInput::setConfiguration() { | ||
| 74 | for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) { | ||
| 75 | QString keyValue = getKeyName(Settings::values.input_mappings[i]); | ||
| 76 | input_mapping[Settings::NativeInput::Values(i)]->setText(keyValue); | ||
| 77 | } | ||
| 78 | } | ||
| 79 | |||
| 80 | void ConfigureInput::keyPressEvent(QKeyEvent* event) { | ||
| 81 | if (!changing_button) | ||
| 82 | return; | ||
| 83 | if (!event || event->key() == Qt::Key_unknown) | ||
| 84 | return; | ||
| 85 | key_pressed = event->key(); | ||
| 86 | timer->stop(); | ||
| 87 | setKey(); | ||
| 88 | } | ||
| 89 | |||
| 90 | void ConfigureInput::setKey() { | ||
| 91 | const QString key_value = getKeyName(key_pressed); | ||
| 92 | if (key_pressed == Qt::Key_Escape) | ||
| 93 | changing_button->setText(previous_mapping); | ||
| 94 | else | ||
| 95 | changing_button->setText(key_value); | ||
| 96 | removeDuplicates(key_value); | ||
| 97 | key_pressed = Qt::Key_unknown; | ||
| 98 | releaseKeyboard(); | ||
| 99 | releaseMouse(); | ||
| 100 | changing_button = nullptr; | ||
| 101 | previous_mapping = nullptr; | ||
| 102 | } | ||
| 103 | |||
| 104 | QString ConfigureInput::getKeyName(int key_code) const { | ||
| 105 | if (key_code == Qt::Key_Shift) | ||
| 106 | return tr("Shift"); | ||
| 107 | if (key_code == Qt::Key_Control) | ||
| 108 | return tr("Ctrl"); | ||
| 109 | if (key_code == Qt::Key_Alt) | ||
| 110 | return tr("Alt"); | ||
| 111 | if (key_code == Qt::Key_Meta) | ||
| 112 | return ""; | ||
| 113 | if (key_code == -1) | ||
| 114 | return ""; | ||
| 115 | |||
| 116 | return QKeySequence(key_code).toString(); | ||
| 117 | } | ||
| 118 | |||
| 119 | Qt::Key ConfigureInput::getKeyValue(const QString& text) const { | ||
| 120 | if (text == "Shift") | ||
| 121 | return Qt::Key_Shift; | ||
| 122 | if (text == "Ctrl") | ||
| 123 | return Qt::Key_Control; | ||
| 124 | if (text == "Alt") | ||
| 125 | return Qt::Key_Alt; | ||
| 126 | if (text == "Meta") | ||
| 127 | return Qt::Key_unknown; | ||
| 128 | if (text == "") | ||
| 129 | return Qt::Key_unknown; | ||
| 130 | |||
| 131 | return Qt::Key(QKeySequence(text)[0]); | ||
| 132 | } | ||
| 133 | |||
| 134 | void ConfigureInput::removeDuplicates(const QString& newValue) { | ||
| 135 | for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) { | ||
| 136 | if (changing_button != input_mapping[Settings::NativeInput::Values(i)]) { | ||
| 137 | const QString oldValue = input_mapping[Settings::NativeInput::Values(i)]->text(); | ||
| 138 | if (newValue == oldValue) | ||
| 139 | input_mapping[Settings::NativeInput::Values(i)]->setText(""); | ||
| 140 | } | ||
| 141 | } | ||
| 142 | } | ||
| 143 | |||
| 144 | void ConfigureInput::restoreDefaults() { | ||
| 145 | for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) { | ||
| 146 | const QString keyValue = getKeyName(Config::defaults[i].toInt()); | ||
| 147 | input_mapping[Settings::NativeInput::Values(i)]->setText(keyValue); | ||
| 148 | } | ||
| 149 | } | ||