mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-06-26 04:16:18 +00:00
Fixed input issues where some inputs would not bind when pressing (side mouse buttons, some symbols, etc). Also, fixed up code formatting in altered files (removed C-style casts and replaced with C++ <static_casts>, added a few macros and one member functions). This is v2 of my commit, addressing all issues brought up by @kalaposfos
948 lines
No EOL
36 KiB
C++
948 lines
No EOL
36 KiB
C++
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
#include <fstream>
|
|
#include <QKeyEvent>
|
|
#include <QMessageBox>
|
|
#include <QMouseEvent>
|
|
#include <QPushButton>
|
|
#include <QWheelEvent>
|
|
|
|
#include "common/path_util.h"
|
|
#include "kbm_config_dialog.h"
|
|
#include "kbm_gui.h"
|
|
#include "kbm_help_dialog.h"
|
|
#include "ui_kbm_gui.h"
|
|
|
|
HelpDialog* HelpWindow;
|
|
KBMSettings::KBMSettings(std::shared_ptr<GameInfoClass> game_info_get, QWidget* parent)
|
|
: QDialog(parent), m_game_info(game_info_get), ui(new Ui::KBMSettings) {
|
|
|
|
ui->setupUi(this);
|
|
ui->PerGameCheckBox->setChecked(!Config::GetUseUnifiedInputConfig());
|
|
ui->TextEditorButton->setFocus();
|
|
this->setFocusPolicy(Qt::StrongFocus);
|
|
|
|
ui->MouseJoystickBox->addItem("none");
|
|
ui->MouseJoystickBox->addItem("right");
|
|
ui->MouseJoystickBox->addItem("left");
|
|
|
|
ui->ProfileComboBox->addItem("Common Config");
|
|
for (int i = 0; i < m_game_info->m_games.size(); i++) {
|
|
ui->ProfileComboBox->addItem(QString::fromStdString(m_game_info->m_games[i].serial));
|
|
}
|
|
|
|
ButtonsList = {
|
|
ui->CrossButton, ui->CircleButton, ui->TriangleButton, ui->SquareButton,
|
|
ui->L1Button, ui->R1Button, ui->L2Button, ui->R2Button,
|
|
ui->L3Button, ui->R3Button, ui->TouchpadButton, ui->OptionsButton,
|
|
ui->TouchpadButton, ui->DpadUpButton, ui->DpadDownButton, ui->DpadLeftButton,
|
|
ui->DpadRightButton, ui->LStickUpButton, ui->LStickDownButton, ui->LStickLeftButton,
|
|
ui->LStickRightButton, ui->RStickUpButton, ui->RStickDownButton, ui->RStickLeftButton,
|
|
ui->RStickRightButton, ui->LHalfButton, ui->RHalfButton};
|
|
|
|
ButtonConnects();
|
|
SetUIValuestoMappings("default");
|
|
installEventFilter(this);
|
|
|
|
ui->ProfileComboBox->setCurrentText("Common Config");
|
|
ui->TitleLabel->setText("Common Config");
|
|
config_id = "default";
|
|
|
|
connect(ui->buttonBox, &QDialogButtonBox::clicked, this, [this](QAbstractButton* button) {
|
|
if (button == ui->buttonBox->button(QDialogButtonBox::Save)) {
|
|
if (HelpWindowOpen) {
|
|
HelpWindow->close();
|
|
HelpWindowOpen = false;
|
|
}
|
|
SaveKBMConfig(true);
|
|
} else if (button == ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)) {
|
|
SetDefault();
|
|
} else if (button == ui->buttonBox->button(QDialogButtonBox::Apply)) {
|
|
SaveKBMConfig(false);
|
|
}
|
|
});
|
|
|
|
ui->buttonBox->button(QDialogButtonBox::Save)->setText(tr("Save"));
|
|
ui->buttonBox->button(QDialogButtonBox::Apply)->setText(tr("Apply"));
|
|
ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)->setText(tr("Restore Defaults"));
|
|
ui->buttonBox->button(QDialogButtonBox::Cancel)->setText(tr("Cancel"));
|
|
|
|
connect(ui->HelpButton, &QPushButton::clicked, this, &KBMSettings::onHelpClicked);
|
|
connect(ui->TextEditorButton, &QPushButton::clicked, this, [this]() {
|
|
auto kbmWindow = new EditorDialog(this);
|
|
kbmWindow->exec();
|
|
SetUIValuestoMappings(config_id);
|
|
});
|
|
|
|
connect(ui->buttonBox, &QDialogButtonBox::rejected, this, [this] {
|
|
QWidget::close();
|
|
if (HelpWindowOpen) {
|
|
HelpWindow->close();
|
|
HelpWindowOpen = false;
|
|
}
|
|
});
|
|
|
|
connect(ui->ProfileComboBox, &QComboBox::currentTextChanged, this, [this] {
|
|
GetGameTitle();
|
|
SetUIValuestoMappings(config_id);
|
|
});
|
|
|
|
connect(ui->CopyCommonButton, &QPushButton::clicked, this, [this] {
|
|
if (ui->ProfileComboBox->currentText() == "Common Config") {
|
|
QMessageBox::information(this, tr("Common Config Selected"),
|
|
// clang-format off
|
|
tr("This button copies mappings from the Common Config to the currently selected profile, and cannot be used when the currently selected profile is the Common Config."));
|
|
// clang-format on
|
|
} else {
|
|
QMessageBox::StandardButton reply =
|
|
QMessageBox::question(this, tr("Copy values from Common Config"),
|
|
// clang-format off
|
|
tr("Do you want to overwrite existing mappings with the mappings from the Common Config?"),
|
|
// clang-format on
|
|
QMessageBox::Yes | QMessageBox::No);
|
|
if (reply == QMessageBox::Yes) {
|
|
SetUIValuestoMappings("default");
|
|
}
|
|
}
|
|
});
|
|
|
|
connect(ui->DeadzoneOffsetSlider, &QSlider::valueChanged, this, [this](int value) {
|
|
QString DOSValue = QString::number(value / 100.0, 'f', 2);
|
|
QString DOSString = tr("Deadzone Offset (def 0.50):") + " " + DOSValue;
|
|
ui->DeadzoneOffsetLabel->setText(DOSString);
|
|
});
|
|
|
|
connect(ui->SpeedMultiplierSlider, &QSlider::valueChanged, this, [this](int value) {
|
|
QString SMSValue = QString::number(value / 10.0, 'f', 1);
|
|
QString SMSString = tr("Speed Multiplier (def 1.0):") + " " + SMSValue;
|
|
ui->SpeedMultiplierLabel->setText(SMSString);
|
|
});
|
|
|
|
connect(ui->SpeedOffsetSlider, &QSlider::valueChanged, this, [this](int value) {
|
|
QString SOSValue = QString::number(value / 1000.0, 'f', 3);
|
|
QString SOSString = tr("Speed Offset (def 0.125):") + " " + SOSValue;
|
|
ui->SpeedOffsetLabel->setText(SOSString);
|
|
});
|
|
}
|
|
|
|
void KBMSettings::ButtonConnects() {
|
|
for (auto& button : ButtonsList) {
|
|
connect(button, &QPushButton::clicked, this, [this, &button]() { StartTimer(button); });
|
|
}
|
|
}
|
|
|
|
void KBMSettings::DisableMappingButtons() {
|
|
for (const auto& i : ButtonsList) {
|
|
i->setEnabled(false);
|
|
}
|
|
}
|
|
|
|
void KBMSettings::EnableMappingButtons() {
|
|
for (const auto& i : ButtonsList) {
|
|
i->setEnabled(true);
|
|
}
|
|
}
|
|
|
|
void KBMSettings::SaveKBMConfig(bool close_on_save) {
|
|
std::string output_string = "", input_string = "";
|
|
std::vector<std::string> lines, inputs;
|
|
|
|
// Comment lines for config file
|
|
lines.push_back("#Feeling lost? Check out the Help section!");
|
|
lines.push_back("");
|
|
lines.push_back("#Keyboard bindings");
|
|
lines.push_back("");
|
|
|
|
// Lambda to reduce repetitive code for mapping buttons to config lines
|
|
auto add_mapping = [&](const QString& buttonText, const std::string& output_name) {
|
|
input_string = buttonText.toStdString();
|
|
output_string = output_name;
|
|
lines.push_back(output_string + " = " + input_string);
|
|
if (input_string != "unmapped") {
|
|
inputs.push_back(input_string);
|
|
}
|
|
};
|
|
|
|
add_mapping(ui->CrossButton->text(), "cross");
|
|
add_mapping(ui->CircleButton->text(), "circle");
|
|
add_mapping(ui->TriangleButton->text(), "triangle");
|
|
add_mapping(ui->SquareButton->text(), "square");
|
|
|
|
lines.push_back("");
|
|
|
|
add_mapping(ui->DpadUpButton->text(), "pad_up");
|
|
add_mapping(ui->DpadDownButton->text(), "pad_down");
|
|
add_mapping(ui->DpadLeftButton->text(), "pad_left");
|
|
add_mapping(ui->DpadRightButton->text(), "pad_right");
|
|
|
|
lines.push_back("");
|
|
|
|
add_mapping(ui->L1Button->text(), "l1");
|
|
add_mapping(ui->R1Button->text(), "r1");
|
|
add_mapping(ui->L2Button->text(), "l2");
|
|
add_mapping(ui->R2Button->text(), "r2");
|
|
add_mapping(ui->L3Button->text(), "l3");
|
|
add_mapping(ui->R3Button->text(), "r3");
|
|
|
|
lines.push_back("");
|
|
|
|
add_mapping(ui->OptionsButton->text(), "options");
|
|
add_mapping(ui->TouchpadButton->text(), "touchpad");
|
|
|
|
lines.push_back("");
|
|
|
|
add_mapping(ui->LStickUpButton->text(), "axis_left_y_minus");
|
|
add_mapping(ui->LStickDownButton->text(), "axis_left_y_plus");
|
|
add_mapping(ui->LStickLeftButton->text(), "axis_left_x_minus");
|
|
add_mapping(ui->LStickRightButton->text(), "axis_left_x_plus");
|
|
|
|
lines.push_back("");
|
|
|
|
add_mapping(ui->RStickUpButton->text(), "axis_right_y_minus");
|
|
add_mapping(ui->RStickDownButton->text(), "axis_right_y_plus");
|
|
add_mapping(ui->RStickLeftButton->text(), "axis_right_x_minus");
|
|
add_mapping(ui->RStickRightButton->text(), "axis_right_x_plus");
|
|
|
|
lines.push_back("");
|
|
|
|
add_mapping(ui->MouseJoystickBox->currentText(), "mouse_to_joystick");
|
|
add_mapping(ui->LHalfButton->text(), "leftjoystick_halfmode");
|
|
add_mapping(ui->RHalfButton->text(), "rightjoystick_halfmode");
|
|
|
|
std::string DOString = std::format("{:.2f}", (ui->DeadzoneOffsetSlider->value() / 100.f));
|
|
std::string SMString = std::format("{:.1f}", (ui->SpeedMultiplierSlider->value() / 10.f));
|
|
std::string SOString = std::format("{:.3f}", (ui->SpeedOffsetSlider->value() / 1000.f));
|
|
input_string = DOString + ", " + SMString + ", " + SOString;
|
|
output_string = "mouse_movement_params";
|
|
lines.push_back(output_string + " = " + input_string);
|
|
|
|
lines.push_back("");
|
|
const auto config_file = Config::GetFoolproofKbmConfigFile(config_id);
|
|
std::fstream file(config_file);
|
|
int lineCount = 0;
|
|
std::string line;
|
|
while (std::getline(file, line)) {
|
|
lineCount++;
|
|
|
|
// remove whitespace from the beginning of the line
|
|
auto line_kpmask = (line.substr(0, 2) == "kp ") ? line.begin() + 2 : line.begin();
|
|
line.erase(std::remove_if(line_kpmask, line.end(),
|
|
[](unsigned char c) { return std::isspace(c); }),
|
|
line.end());
|
|
|
|
if (line.empty()) {
|
|
lines.push_back(line);
|
|
continue;
|
|
}
|
|
|
|
std::size_t comment_pos = line.find('#');
|
|
if (comment_pos != std::string::npos) {
|
|
if (!line.contains("Keyboard bindings") && !line.contains("Feeling lost") &&
|
|
!line.contains("Alternatives for users"))
|
|
lines.push_back(line);
|
|
continue;
|
|
}
|
|
|
|
std::size_t equal_pos = line.find('=');
|
|
if (equal_pos == std::string::npos) {
|
|
lines.push_back(line);
|
|
continue;
|
|
}
|
|
|
|
output_string = line.substr(0, equal_pos - 1);
|
|
input_string = line.substr(equal_pos + 2);
|
|
|
|
if (std::find(ControllerInputs.begin(), ControllerInputs.end(), input_string) !=
|
|
ControllerInputs.end() ||
|
|
output_string == "analog_deadzone" || output_string == "override_controller_color") {
|
|
lines.push_back(line);
|
|
}
|
|
}
|
|
file.close();
|
|
|
|
// Prevent duplicate inputs for KBM as this breaks the engine
|
|
for (auto it = inputs.begin(); it != inputs.end(); ++it) {
|
|
if (std::find(it + 1, inputs.end(), *it) != inputs.end()) {
|
|
QMessageBox::information(this, tr("Unable to Save"),
|
|
tr("Cannot bind any unique input more than once"));
|
|
return;
|
|
}
|
|
}
|
|
|
|
std::vector<std::string> save;
|
|
bool CurrentLineEmpty = false, LastLineEmpty = false;
|
|
for (auto const& line : lines) {
|
|
LastLineEmpty = CurrentLineEmpty ? true : false;
|
|
CurrentLineEmpty = line.empty() ? true : false;
|
|
if (!CurrentLineEmpty || !LastLineEmpty)
|
|
save.push_back(line);
|
|
}
|
|
|
|
std::ofstream output_file(config_file);
|
|
for (auto const& line : save) {
|
|
output_file << line << '\n';
|
|
}
|
|
output_file.close();
|
|
|
|
Config::SetUseUnifiedInputConfig(!ui->PerGameCheckBox->isChecked());
|
|
Config::save(Common::FS::GetUserPath(Common::FS::PathType::UserDir) / "config.toml");
|
|
|
|
if (close_on_save)
|
|
QWidget::close();
|
|
}
|
|
|
|
void KBMSettings::SetDefault() {
|
|
ui->CrossButton->setText("kp 2");
|
|
ui->CircleButton->setText("kp 6");
|
|
ui->TriangleButton->setText("kp 8");
|
|
ui->SquareButton->setText("kp 4");
|
|
|
|
ui->L1Button->setText("q");
|
|
ui->L2Button->setText("e");
|
|
ui->L3Button->setText("x");
|
|
ui->R1Button->setText("u");
|
|
ui->R2Button->setText("o");
|
|
ui->R3Button->setText("m");
|
|
|
|
ui->TouchpadButton->setText("space");
|
|
ui->OptionsButton->setText("enter");
|
|
|
|
ui->DpadUpButton->setText("up");
|
|
ui->DpadDownButton->setText("down");
|
|
ui->DpadLeftButton->setText("left");
|
|
ui->DpadRightButton->setText("right");
|
|
|
|
ui->LStickUpButton->setText("w");
|
|
ui->LStickDownButton->setText("s");
|
|
ui->LStickLeftButton->setText("a");
|
|
ui->LStickRightButton->setText("d");
|
|
|
|
ui->RStickUpButton->setText("i");
|
|
ui->RStickDownButton->setText("k");
|
|
ui->RStickLeftButton->setText("j");
|
|
ui->RStickRightButton->setText("l");
|
|
|
|
ui->LHalfButton->setText("unmapped");
|
|
ui->RHalfButton->setText("unmapped");
|
|
|
|
ui->MouseJoystickBox->setCurrentText("none");
|
|
ui->DeadzoneOffsetSlider->setValue(50);
|
|
ui->SpeedMultiplierSlider->setValue(10);
|
|
ui->SpeedOffsetSlider->setValue(125);
|
|
}
|
|
|
|
void KBMSettings::SetUIValuestoMappings(std::string config_id) {
|
|
const auto config_file = Config::GetFoolproofKbmConfigFile(config_id);
|
|
std::ifstream file(config_file);
|
|
|
|
int lineCount = 0;
|
|
std::string line = "";
|
|
while (std::getline(file, line)) {
|
|
lineCount++;
|
|
|
|
std::size_t comment_pos = line.find('#');
|
|
if (comment_pos != std::string::npos)
|
|
line = line.substr(0, comment_pos);
|
|
|
|
std::size_t equal_pos = line.find('=');
|
|
if (equal_pos == std::string::npos)
|
|
continue;
|
|
|
|
std::string output_string = line.substr(0, equal_pos - 1);
|
|
std::string input_string = line.substr(equal_pos + 2);
|
|
|
|
if (std::find(ControllerInputs.begin(), ControllerInputs.end(), input_string) ==
|
|
ControllerInputs.end()) {
|
|
|
|
if (output_string == "cross") {
|
|
ui->CrossButton->setText(QString::fromStdString(input_string));
|
|
} else if (output_string == "circle") {
|
|
ui->CircleButton->setText(QString::fromStdString(input_string));
|
|
} else if (output_string == "square") {
|
|
ui->SquareButton->setText(QString::fromStdString(input_string));
|
|
} else if (output_string == "triangle") {
|
|
ui->TriangleButton->setText(QString::fromStdString(input_string));
|
|
} else if (output_string == "l1") {
|
|
ui->L1Button->setText(QString::fromStdString(input_string));
|
|
} else if (output_string == "l2") {
|
|
ui->L2Button->setText(QString::fromStdString(input_string));
|
|
} else if (output_string == "r1") {
|
|
ui->R1Button->setText(QString::fromStdString(input_string));
|
|
} else if (output_string == "r2") {
|
|
ui->R2Button->setText(QString::fromStdString(input_string));
|
|
} else if (output_string == "l3") {
|
|
ui->L3Button->setText(QString::fromStdString(input_string));
|
|
} else if (output_string == "r3") {
|
|
ui->R3Button->setText(QString::fromStdString(input_string));
|
|
} else if (output_string == "pad_up") {
|
|
ui->DpadUpButton->setText(QString::fromStdString(input_string));
|
|
} else if (output_string == "pad_down") {
|
|
ui->DpadDownButton->setText(QString::fromStdString(input_string));
|
|
} else if (output_string == "pad_left") {
|
|
ui->DpadLeftButton->setText(QString::fromStdString(input_string));
|
|
} else if (output_string == "pad_right") {
|
|
ui->DpadRightButton->setText(QString::fromStdString(input_string));
|
|
} else if (output_string == "options") {
|
|
ui->OptionsButton->setText(QString::fromStdString(input_string));
|
|
} else if (output_string == "touchpad") {
|
|
ui->TouchpadButton->setText(QString::fromStdString(input_string));
|
|
} else if (output_string == "axis_left_x_minus") {
|
|
ui->LStickLeftButton->setText(QString::fromStdString(input_string));
|
|
} else if (output_string == "axis_left_x_plus") {
|
|
ui->LStickRightButton->setText(QString::fromStdString(input_string));
|
|
} else if (output_string == "axis_left_y_minus") {
|
|
ui->LStickUpButton->setText(QString::fromStdString(input_string));
|
|
} else if (output_string == "axis_left_y_plus") {
|
|
ui->LStickDownButton->setText(QString::fromStdString(input_string));
|
|
} else if (output_string == "axis_right_x_minus") {
|
|
ui->RStickLeftButton->setText(QString::fromStdString(input_string));
|
|
} else if (output_string == "axis_right_x_plus") {
|
|
ui->RStickRightButton->setText(QString::fromStdString(input_string));
|
|
} else if (output_string == "axis_right_y_minus") {
|
|
ui->RStickUpButton->setText(QString::fromStdString(input_string));
|
|
} else if (output_string == "axis_right_y_plus") {
|
|
ui->RStickDownButton->setText(QString::fromStdString(input_string));
|
|
} else if (output_string == "mouse_to_joystick") {
|
|
ui->MouseJoystickBox->setCurrentText(QString::fromStdString(input_string));
|
|
} else if (output_string == "leftjoystick_halfmode") {
|
|
ui->LHalfButton->setText(QString::fromStdString(input_string));
|
|
} else if (output_string == "rightjoystick_halfmode") {
|
|
ui->RHalfButton->setText(QString::fromStdString(input_string));
|
|
} else if (output_string.contains("mouse_movement_params")) {
|
|
std::size_t comma_pos = line.find(',');
|
|
if (comma_pos != std::string::npos) {
|
|
std::string DOstring = line.substr(equal_pos + 1, comma_pos);
|
|
float DOffsetValue = std::stof(DOstring) * 100.0;
|
|
int DOffsetInt = int(DOffsetValue);
|
|
ui->DeadzoneOffsetSlider->setValue(DOffsetInt);
|
|
QString LabelValue = QString::number(DOffsetInt / 100.0, 'f', 2);
|
|
QString LabelString = tr("Deadzone Offset (def 0.50):") + " " + LabelValue;
|
|
ui->DeadzoneOffsetLabel->setText(LabelString);
|
|
|
|
std::string SMSOstring = line.substr(comma_pos + 1);
|
|
std::size_t comma_pos2 = SMSOstring.find(',');
|
|
if (comma_pos2 != std::string::npos) {
|
|
std::string SMstring = SMSOstring.substr(0, comma_pos2);
|
|
float SpeedMultValue = std::stof(SMstring) * 10.0;
|
|
int SpeedMultInt = int(SpeedMultValue);
|
|
if (SpeedMultInt < 1)
|
|
SpeedMultInt = 1;
|
|
if (SpeedMultInt > 50)
|
|
SpeedMultInt = 50;
|
|
ui->SpeedMultiplierSlider->setValue(SpeedMultInt);
|
|
LabelValue = QString::number(SpeedMultInt / 10.0, 'f', 1);
|
|
LabelString = tr("Speed Multiplier (def 1.0):") + " " + LabelValue;
|
|
ui->SpeedMultiplierLabel->setText(LabelString);
|
|
|
|
std::string SOstring = SMSOstring.substr(comma_pos2 + 1);
|
|
float SOffsetValue = std::stof(SOstring) * 1000.0;
|
|
int SOffsetInt = int(SOffsetValue);
|
|
ui->SpeedOffsetSlider->setValue(SOffsetInt);
|
|
LabelValue = QString::number(SOffsetInt / 1000.0, 'f', 3);
|
|
LabelString = tr("Speed Offset (def 0.125):") + " " + LabelValue;
|
|
ui->SpeedOffsetLabel->setText(LabelString);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
file.close();
|
|
}
|
|
|
|
void KBMSettings::GetGameTitle() {
|
|
if (ui->ProfileComboBox->currentText() == "Common Config") {
|
|
ui->TitleLabel->setText("Common Config");
|
|
} else {
|
|
for (int i = 0; i < m_game_info->m_games.size(); i++) {
|
|
if (m_game_info->m_games[i].serial ==
|
|
ui->ProfileComboBox->currentText().toStdString()) {
|
|
ui->TitleLabel->setText(QString::fromStdString(m_game_info->m_games[i].name));
|
|
}
|
|
}
|
|
}
|
|
config_id = (ui->ProfileComboBox->currentText() == "Common Config")
|
|
? "default"
|
|
: ui->ProfileComboBox->currentText().toStdString();
|
|
}
|
|
|
|
void KBMSettings::onHelpClicked() {
|
|
if (!HelpWindowOpen) {
|
|
HelpWindow = new HelpDialog(&HelpWindowOpen, this);
|
|
HelpWindow->setWindowTitle(tr("Help"));
|
|
HelpWindow->setAttribute(Qt::WA_DeleteOnClose); // Clean up on close
|
|
HelpWindow->show();
|
|
HelpWindowOpen = true;
|
|
} else {
|
|
HelpWindow->close();
|
|
HelpWindowOpen = false;
|
|
}
|
|
}
|
|
|
|
void KBMSettings::StartTimer(QPushButton*& button) {
|
|
MappingTimer = 3;
|
|
EnableMapping = true;
|
|
MappingCompleted = false;
|
|
modifier = "";
|
|
mapping = button->text();
|
|
|
|
DisableMappingButtons();
|
|
button->setText(tr("Press a key") + " [" + QString::number(MappingTimer) + "]");
|
|
timer = new QTimer(this);
|
|
MappingButton = button;
|
|
connect(timer, &QTimer::timeout, this, [this]() { CheckMapping(MappingButton); });
|
|
timer->start(1000);
|
|
}
|
|
|
|
void KBMSettings::CheckMapping(QPushButton*& button) {
|
|
MappingTimer -= 1;
|
|
button->setText(tr("Press a key") + " [" + QString::number(MappingTimer) + "]");
|
|
|
|
if (pressedKeys.size() > 0) {
|
|
QStringList keyStrings;
|
|
|
|
for (const QString& buttonAction : pressedKeys) {
|
|
keyStrings << buttonAction;
|
|
}
|
|
|
|
QString combo = keyStrings.join(",");
|
|
SetMapping(combo);
|
|
MappingCompleted = true;
|
|
EnableMapping = false;
|
|
|
|
MappingButton->setText(combo);
|
|
pressedKeys.clear();
|
|
timer->stop();
|
|
}
|
|
if (MappingCompleted) {
|
|
EnableMapping = false;
|
|
EnableMappingButtons();
|
|
timer->stop();
|
|
|
|
button->setText(mapping);
|
|
}
|
|
|
|
if (MappingTimer <= 0) {
|
|
button->setText(mapping);
|
|
EnableMapping = false;
|
|
EnableMappingButtons();
|
|
timer->stop();
|
|
}
|
|
}
|
|
|
|
void KBMSettings::SetMapping(QString input) {
|
|
mapping = input;
|
|
MappingCompleted = true;
|
|
}
|
|
|
|
// Helper lambda to get the modified button text based on the current keyboard modifiers
|
|
auto GetModifiedButton = [](Qt::KeyboardModifiers modifier,
|
|
const std::string& m_button, const std::string& n_button) -> QString {
|
|
if (QApplication::keyboardModifiers() & modifier) {
|
|
return QString::fromStdString(m_button);
|
|
} else {
|
|
return QString::fromStdString(n_button);
|
|
}
|
|
};
|
|
|
|
bool KBMSettings::eventFilter(QObject* obj, QEvent* event) {
|
|
if (event->type() == QEvent::Close) {
|
|
if (HelpWindowOpen) {
|
|
HelpWindow->close();
|
|
HelpWindowOpen = false;
|
|
}
|
|
}
|
|
|
|
if (EnableMapping) {
|
|
if (event->type() == QEvent::KeyPress) {
|
|
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
|
|
|
|
if (keyEvent->isAutoRepeat())
|
|
return true;
|
|
|
|
if (pressedKeys.size() >= 3) {
|
|
return true;
|
|
}
|
|
|
|
switch (keyEvent->key()) {
|
|
// alphanumeric
|
|
case Qt::Key_A:
|
|
pressedKeys.insert("a");
|
|
break;
|
|
case Qt::Key_B:
|
|
pressedKeys.insert("b");
|
|
break;
|
|
case Qt::Key_C:
|
|
pressedKeys.insert("c");
|
|
break;
|
|
case Qt::Key_D:
|
|
pressedKeys.insert("d");
|
|
break;
|
|
case Qt::Key_E:
|
|
pressedKeys.insert("e");
|
|
break;
|
|
case Qt::Key_F:
|
|
pressedKeys.insert("f");
|
|
break;
|
|
case Qt::Key_G:
|
|
pressedKeys.insert("g");
|
|
break;
|
|
case Qt::Key_H:
|
|
pressedKeys.insert("h");
|
|
break;
|
|
case Qt::Key_I:
|
|
pressedKeys.insert("i");
|
|
break;
|
|
case Qt::Key_J:
|
|
pressedKeys.insert("j");
|
|
break;
|
|
case Qt::Key_K:
|
|
pressedKeys.insert("k");
|
|
break;
|
|
case Qt::Key_L:
|
|
pressedKeys.insert("l");
|
|
break;
|
|
case Qt::Key_M:
|
|
pressedKeys.insert("m");
|
|
break;
|
|
case Qt::Key_N:
|
|
pressedKeys.insert("n");
|
|
break;
|
|
case Qt::Key_O:
|
|
pressedKeys.insert("o");
|
|
break;
|
|
case Qt::Key_P:
|
|
pressedKeys.insert("p");
|
|
break;
|
|
case Qt::Key_Q:
|
|
pressedKeys.insert("q");
|
|
break;
|
|
case Qt::Key_R:
|
|
pressedKeys.insert("r");
|
|
break;
|
|
case Qt::Key_S:
|
|
pressedKeys.insert("s");
|
|
break;
|
|
case Qt::Key_T:
|
|
pressedKeys.insert("t");
|
|
break;
|
|
case Qt::Key_U:
|
|
pressedKeys.insert("u");
|
|
break;
|
|
case Qt::Key_V:
|
|
pressedKeys.insert("v");
|
|
break;
|
|
case Qt::Key_W:
|
|
pressedKeys.insert("w");
|
|
break;
|
|
case Qt::Key_X:
|
|
pressedKeys.insert("x");
|
|
break;
|
|
case Qt::Key_Y:
|
|
pressedKeys.insert("y");
|
|
break;
|
|
case Qt::Key_Z:
|
|
pressedKeys.insert("z");
|
|
break;
|
|
case Qt::Key_0:
|
|
pressedKeys.insert(GetModifiedButton(Qt::KeypadModifier, "kp 0", "0"));
|
|
break;
|
|
case Qt::Key_1:
|
|
pressedKeys.insert(GetModifiedButton(Qt::KeypadModifier, "kp 1", "1"));
|
|
break;
|
|
case Qt::Key_2:
|
|
pressedKeys.insert(GetModifiedButton(Qt::KeypadModifier, "kp 2", "2"));
|
|
break;
|
|
case Qt::Key_3:
|
|
pressedKeys.insert(GetModifiedButton(Qt::KeypadModifier, "kp 3", "3"));
|
|
break;
|
|
case Qt::Key_4:
|
|
pressedKeys.insert(GetModifiedButton(Qt::KeypadModifier, "kp 4", "4"));
|
|
break;
|
|
case Qt::Key_5:
|
|
pressedKeys.insert(GetModifiedButton(Qt::KeypadModifier, "kp 5", "5"));
|
|
break;
|
|
case Qt::Key_6:
|
|
pressedKeys.insert(GetModifiedButton(Qt::KeypadModifier, "kp 6", "6"));
|
|
break;
|
|
case Qt::Key_7:
|
|
pressedKeys.insert(GetModifiedButton(Qt::KeypadModifier, "kp 7", "7"));
|
|
break;
|
|
case Qt::Key_8:
|
|
pressedKeys.insert(GetModifiedButton(Qt::KeypadModifier, "kp 8", "8"));
|
|
break;
|
|
case Qt::Key_9:
|
|
pressedKeys.insert(GetModifiedButton(Qt::KeypadModifier, "kp 9", "9"));
|
|
break;
|
|
|
|
// symbols
|
|
case Qt::Key_Exclam:
|
|
pressedKeys.insert("!");
|
|
break;
|
|
case Qt::Key_At:
|
|
pressedKeys.insert("@");
|
|
break;
|
|
case Qt::Key_NumberSign:
|
|
pressedKeys.insert("#");
|
|
break;
|
|
case Qt::Key_Dollar:
|
|
pressedKeys.insert("$");
|
|
break;
|
|
case Qt::Key_Percent:
|
|
pressedKeys.insert("%");
|
|
break;
|
|
case Qt::Key_AsciiCircum:
|
|
pressedKeys.insert("^");
|
|
break;
|
|
case Qt::Key_Ampersand:
|
|
pressedKeys.insert("&");
|
|
break;
|
|
case Qt::Key_Asterisk:
|
|
pressedKeys.insert(GetModifiedButton(Qt::KeypadModifier, "kp *", "*"));
|
|
break;
|
|
case Qt::Key_ParenLeft:
|
|
pressedKeys.insert("(");
|
|
break;
|
|
case Qt::Key_ParenRight:
|
|
pressedKeys.insert(")");
|
|
break;
|
|
case Qt::Key_Minus:
|
|
pressedKeys.insert(GetModifiedButton(Qt::KeypadModifier, "kp -", "-"));
|
|
break;
|
|
case Qt::Key_Underscore:
|
|
pressedKeys.insert("_");
|
|
break;
|
|
case Qt::Key_Equal:
|
|
pressedKeys.insert(GetModifiedButton(Qt::KeypadModifier, "kp =", "="));
|
|
break;
|
|
case Qt::Key_Plus:
|
|
pressedKeys.insert(GetModifiedButton(Qt::KeypadModifier, "kp +", "+"));
|
|
break;
|
|
case Qt::Key_BracketLeft:
|
|
pressedKeys.insert("[");
|
|
break;
|
|
case Qt::Key_BracketRight:
|
|
pressedKeys.insert("]");
|
|
break;
|
|
case Qt::Key_BraceLeft:
|
|
pressedKeys.insert("{");
|
|
break;
|
|
case Qt::Key_BraceRight:
|
|
pressedKeys.insert("}");
|
|
break;
|
|
case Qt::Key_Backslash:
|
|
pressedKeys.insert("\\");
|
|
break;
|
|
case Qt::Key_Bar:
|
|
pressedKeys.insert("|");
|
|
break;
|
|
case Qt::Key_Semicolon:
|
|
pressedKeys.insert(";");
|
|
break;
|
|
case Qt::Key_Colon:
|
|
pressedKeys.insert(":");
|
|
break;
|
|
case Qt::Key_Apostrophe:
|
|
pressedKeys.insert("'");
|
|
break;
|
|
case Qt::Key_QuoteDbl:
|
|
pressedKeys.insert("\"");
|
|
break;
|
|
case Qt::Key_Comma:
|
|
pressedKeys.insert(GetModifiedButton(Qt::KeypadModifier, "kp ,", ","));
|
|
break;
|
|
case Qt::Key_Less:
|
|
pressedKeys.insert("<");
|
|
break;
|
|
case Qt::Key_Period:
|
|
pressedKeys.insert(GetModifiedButton(Qt::KeypadModifier, "kp .", "."));
|
|
break;
|
|
case Qt::Key_Greater:
|
|
pressedKeys.insert(">");
|
|
break;
|
|
case Qt::Key_Slash:
|
|
pressedKeys.insert(GetModifiedButton(Qt::KeypadModifier, "kp /", "/"));
|
|
break;
|
|
case Qt::Key_Question:
|
|
pressedKeys.insert("question");
|
|
break;
|
|
|
|
// special keys
|
|
case Qt::Key_Print:
|
|
pressedKeys.insert("printscreen");
|
|
break;
|
|
case Qt::Key_ScrollLock:
|
|
pressedKeys.insert("scrolllock");
|
|
break;
|
|
case Qt::Key_Pause:
|
|
pressedKeys.insert("pausebreak");
|
|
break;
|
|
case Qt::Key_Backspace:
|
|
pressedKeys.insert("backspace");
|
|
break;
|
|
case Qt::Key_Insert:
|
|
pressedKeys.insert("insert");
|
|
break;
|
|
case Qt::Key_Delete:
|
|
pressedKeys.insert("delete");
|
|
break;
|
|
case Qt::Key_Home:
|
|
pressedKeys.insert("home");
|
|
break;
|
|
case Qt::Key_End:
|
|
pressedKeys.insert("end");
|
|
break;
|
|
case Qt::Key_PageUp:
|
|
pressedKeys.insert("pgup");
|
|
break;
|
|
case Qt::Key_PageDown:
|
|
pressedKeys.insert("pgdown");
|
|
break;
|
|
case Qt::Key_Tab:
|
|
pressedKeys.insert("tab");
|
|
break;
|
|
case Qt::Key_CapsLock:
|
|
pressedKeys.insert("capslock");
|
|
break;
|
|
case Qt::Key_Return:
|
|
pressedKeys.insert("enter");
|
|
break;
|
|
case Qt::Key_Enter:
|
|
pressedKeys.insert(GetModifiedButton(Qt::ShiftModifier, "kp enter", "enter"));
|
|
break;
|
|
case Qt::Key_Shift:
|
|
if (keyEvent->nativeScanCode() == LSHIFT_KEY) {
|
|
pressedKeys.insert("lshift");
|
|
} else {
|
|
pressedKeys.insert("rshift");
|
|
}
|
|
break;
|
|
case Qt::Key_Alt:
|
|
if (keyEvent->nativeScanCode() == LALT_KEY) {
|
|
pressedKeys.insert("lalt");
|
|
} else {
|
|
pressedKeys.insert("ralt");
|
|
}
|
|
break;
|
|
case Qt::Key_Control:
|
|
if (keyEvent->nativeScanCode() == LCTRL_KEY) {
|
|
pressedKeys.insert("lctrl");
|
|
} else {
|
|
pressedKeys.insert("rctrl");
|
|
}
|
|
break;
|
|
case Qt::Key_Meta:
|
|
activateWindow();
|
|
#ifdef _WIN32
|
|
pressedKeys.insert("lwin");
|
|
#else
|
|
pressedKeys.insert("lmeta");
|
|
#endif
|
|
break;
|
|
case Qt::Key_Space:
|
|
pressedKeys.insert("space");
|
|
break;
|
|
case Qt::Key_Up:
|
|
activateWindow();
|
|
pressedKeys.insert("up");
|
|
break;
|
|
case Qt::Key_Down:
|
|
pressedKeys.insert("down");
|
|
break;
|
|
case Qt::Key_Left:
|
|
pressedKeys.insert("left");
|
|
break;
|
|
case Qt::Key_Right:
|
|
pressedKeys.insert("right");
|
|
break;
|
|
|
|
// cancel mapping
|
|
case Qt::Key_Escape:
|
|
pressedKeys.insert("unmapped");
|
|
break;
|
|
|
|
// default case
|
|
default:
|
|
break;
|
|
// bottom text
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
|
|
if (event->type() == QEvent::MouseButtonPress) {
|
|
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
|
|
if (pressedKeys.size() < 3) {
|
|
switch (mouseEvent->button()) {
|
|
case Qt::LeftButton:
|
|
pressedKeys.insert("leftbutton");
|
|
break;
|
|
case Qt::RightButton:
|
|
pressedKeys.insert("rightbutton");
|
|
break;
|
|
case Qt::MiddleButton:
|
|
pressedKeys.insert("middlebutton");
|
|
break;
|
|
case Qt::XButton1:
|
|
pressedKeys.insert("sidebuttonback");
|
|
break;
|
|
case Qt::XButton2:
|
|
pressedKeys.insert("sidebuttonforward");
|
|
break;
|
|
|
|
// default case
|
|
default:
|
|
break;
|
|
// bottom text
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
|
|
const QList<QPushButton*> AxisList = {
|
|
ui->LStickUpButton, ui->LStickDownButton, ui->LStickLeftButton, ui->LStickRightButton,
|
|
ui->RStickUpButton, ui->LStickDownButton, ui->LStickLeftButton, ui->RStickRightButton};
|
|
|
|
if (event->type() == QEvent::Wheel) {
|
|
QWheelEvent* wheelEvent = static_cast<QWheelEvent*>(event);
|
|
if (pressedKeys.size() < 3) {
|
|
if (wheelEvent->angleDelta().y() > 5) {
|
|
if (std::find(AxisList.begin(), AxisList.end(), MappingButton) == AxisList.end()) {
|
|
pressedKeys.insert("mousewheelup");
|
|
} else {
|
|
QMessageBox::information(this, tr("Cannot set mapping"),
|
|
tr("Mousewheel cannot be mapped to stick outputs"));
|
|
}
|
|
} else if (wheelEvent->angleDelta().y() < -5) {
|
|
if (std::find(AxisList.begin(), AxisList.end(), MappingButton) == AxisList.end()) {
|
|
pressedKeys.insert("mousewheeldown");
|
|
} else {
|
|
QMessageBox::information(this, tr("Cannot set mapping"),
|
|
tr("Mousewheel cannot be mapped to stick outputs"));
|
|
}
|
|
}
|
|
if (wheelEvent->angleDelta().x() > 5) {
|
|
if (std::find(AxisList.begin(), AxisList.end(), MappingButton) == AxisList.end()) {
|
|
// QT changes scrolling to horizontal for all widgets with the alt modifier
|
|
pressedKeys.insert(GetModifiedButton(Qt::AltModifier,
|
|
"mousewheelup", "mousewheelright"));
|
|
} else {
|
|
QMessageBox::information(this, tr("Cannot set mapping"),
|
|
tr("Mousewheel cannot be mapped to stick outputs"));
|
|
}
|
|
} else if (wheelEvent->angleDelta().x() < -5) {
|
|
if (std::find(AxisList.begin(), AxisList.end(), MappingButton) == AxisList.end()) {
|
|
pressedKeys.insert(GetModifiedButton(Qt::AltModifier,
|
|
"mousewheeldown", "mousewheelleft"));
|
|
} else {
|
|
QMessageBox::information(this, tr("Cannot set mapping"),
|
|
tr("Mousewheel cannot be mapped to stick outputs"));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return QDialog::eventFilter(obj, event);
|
|
}
|
|
|
|
KBMSettings::~KBMSettings() {} |