Various input profile changes.
- Saves and loads the selected profile between sessions. - Profiles only save when config window is confirmed. - Can map multiple players at the same time if they have the same profile. - Adds rename button.
This commit is contained in:
@@ -106,6 +106,13 @@ struct TouchFromButtonMap {
|
||||
std::vector<std::string> buttons;
|
||||
};
|
||||
|
||||
struct InputProfile {
|
||||
ControllerType controller_type;
|
||||
ButtonsRaw buttons;
|
||||
AnalogsRaw analogs;
|
||||
MotionsRaw motions;
|
||||
};
|
||||
|
||||
struct Values {
|
||||
// Audio
|
||||
std::string audio_device_id;
|
||||
|
||||
@@ -357,6 +357,8 @@ struct PlayerInput {
|
||||
u32 body_color_right;
|
||||
u32 button_color_left;
|
||||
u32 button_color_right;
|
||||
|
||||
std::string input_profile;
|
||||
};
|
||||
|
||||
struct TouchscreenInput {
|
||||
|
||||
@@ -295,6 +295,11 @@ void Config::ReadPlayerValue(std::size_t player_index) {
|
||||
ReadSetting(QStringLiteral("%1connected").arg(player_prefix), player_index == 0)
|
||||
.toBool();
|
||||
|
||||
player.input_profile =
|
||||
qt_config->value(QStringLiteral("%1input_profile").arg(player_prefix), QString{})
|
||||
.toString()
|
||||
.toStdString();
|
||||
|
||||
player.controller_type = static_cast<Settings::ControllerType>(
|
||||
qt_config
|
||||
->value(QStringLiteral("%1type").arg(player_prefix),
|
||||
@@ -1006,6 +1011,8 @@ void Config::SavePlayerValue(std::size_t player_index) {
|
||||
|
||||
if (!player_prefix.isEmpty()) {
|
||||
WriteSetting(QStringLiteral("%1connected").arg(player_prefix), player.connected, false);
|
||||
WriteSetting(QStringLiteral("%1input_profile").arg(player_prefix),
|
||||
QString::fromStdString(player.input_profile), QString{});
|
||||
WriteSetting(QStringLiteral("%1vibration_enabled").arg(player_prefix),
|
||||
player.vibration_enabled, true);
|
||||
WriteSetting(QStringLiteral("%1vibration_strength").arg(player_prefix),
|
||||
@@ -1617,3 +1624,88 @@ void Config::SaveControlPlayerValue(std::size_t player_index) {
|
||||
const std::string& Config::GetConfigFilePath() const {
|
||||
return qt_config_loc;
|
||||
}
|
||||
|
||||
void Config::ReadToProfileStruct(Settings::InputProfile& profile) {
|
||||
qt_config->beginGroup(QStringLiteral("Controls"));
|
||||
|
||||
profile.controller_type = static_cast<Settings::ControllerType>(
|
||||
qt_config
|
||||
->value(QStringLiteral("type"),
|
||||
static_cast<u8>(Settings::ControllerType::ProController))
|
||||
.toUInt());
|
||||
|
||||
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
|
||||
const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
|
||||
auto& player_buttons = profile.buttons[i];
|
||||
|
||||
player_buttons = qt_config
|
||||
->value(QString::fromUtf8(Settings::NativeButton::mapping[i]),
|
||||
QString::fromStdString(default_param))
|
||||
.toString()
|
||||
.toStdString();
|
||||
if (player_buttons.empty()) {
|
||||
player_buttons = default_param;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
|
||||
const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
|
||||
default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
|
||||
default_analogs[i][3], default_stick_mod[i], 0.5f);
|
||||
auto& player_analogs = profile.analogs[i];
|
||||
|
||||
player_analogs = qt_config
|
||||
->value(QString::fromUtf8(Settings::NativeAnalog::mapping[i]),
|
||||
QString::fromStdString(default_param))
|
||||
.toString()
|
||||
.toStdString();
|
||||
if (player_analogs.empty()) {
|
||||
player_analogs = default_param;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < Settings::NativeMotion::NumMotions; ++i) {
|
||||
const std::string default_param = InputCommon::GenerateKeyboardParam(default_motions[i]);
|
||||
auto& player_motions = profile.motions[i];
|
||||
|
||||
player_motions = qt_config
|
||||
->value(QString::fromUtf8(Settings::NativeMotion::mapping[i]),
|
||||
QString::fromStdString(default_param))
|
||||
.toString()
|
||||
.toStdString();
|
||||
if (player_motions.empty()) {
|
||||
player_motions = default_param;
|
||||
}
|
||||
}
|
||||
|
||||
qt_config->endGroup();
|
||||
}
|
||||
|
||||
void Config::WriteFromProfileStruct(const Settings::InputProfile& profile) {
|
||||
qt_config->beginGroup(QStringLiteral("Controls"));
|
||||
|
||||
WriteSetting(QStringLiteral("type"), static_cast<u8>(profile.controller_type),
|
||||
static_cast<u8>(Settings::ControllerType::ProController));
|
||||
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
|
||||
const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
|
||||
WriteSetting(QString::fromStdString(Settings::NativeButton::mapping[i]),
|
||||
QString::fromStdString(profile.buttons[i]),
|
||||
QString::fromStdString(default_param));
|
||||
}
|
||||
for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
|
||||
const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
|
||||
default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
|
||||
default_analogs[i][3], default_stick_mod[i], 0.5f);
|
||||
WriteSetting(QString::fromStdString(Settings::NativeAnalog::mapping[i]),
|
||||
QString::fromStdString(profile.analogs[i]),
|
||||
QString::fromStdString(default_param));
|
||||
}
|
||||
for (int i = 0; i < Settings::NativeMotion::NumMotions; ++i) {
|
||||
const std::string default_param = InputCommon::GenerateKeyboardParam(default_motions[i]);
|
||||
WriteSetting(QString::fromStdString(Settings::NativeMotion::mapping[i]),
|
||||
QString::fromStdString(profile.motions[i]),
|
||||
QString::fromStdString(default_param));
|
||||
}
|
||||
|
||||
qt_config->endGroup();
|
||||
}
|
||||
|
||||
@@ -31,6 +31,8 @@ public:
|
||||
|
||||
void ReadControlPlayerValue(std::size_t player_index);
|
||||
void SaveControlPlayerValue(std::size_t player_index);
|
||||
void ReadToProfileStruct(Settings::InputProfile& profile);
|
||||
void WriteFromProfileStruct(const Settings::InputProfile& profile);
|
||||
|
||||
const std::string& GetConfigFilePath() const;
|
||||
|
||||
|
||||
@@ -129,6 +129,12 @@ void ConfigureInput::Initialize(InputCommon::InputSubsystem* input_subsystem,
|
||||
&ConfigureInput::UpdateAllInputDevices);
|
||||
connect(player_controllers[i], &ConfigureInputPlayer::RefreshInputProfiles, this,
|
||||
&ConfigureInput::UpdateAllInputProfiles, Qt::QueuedConnection);
|
||||
connect(player_controllers[i], &ConfigureInputPlayer::InputProfileDeleted, this,
|
||||
&ConfigureInput::LoadAllProfiles);
|
||||
connect(player_controllers[i], &ConfigureInputPlayer::InputProfileRenamed, this,
|
||||
&ConfigureInput::RenameInputProfile, Qt::QueuedConnection);
|
||||
connect(player_controllers[i], &ConfigureInputPlayer::PlayerTabSelected, this,
|
||||
&ConfigureInput::TabWindowChanged);
|
||||
connect(player_connected[i], &QCheckBox::stateChanged, [this, i](int state) {
|
||||
player_controllers[i]->ConnectPlayer(state == Qt::Checked);
|
||||
});
|
||||
@@ -182,7 +188,11 @@ QList<QWidget*> ConfigureInput::GetSubTabs() const {
|
||||
}
|
||||
|
||||
void ConfigureInput::ApplyConfiguration() {
|
||||
player_controllers[current_tab]->SaveProfile(
|
||||
player_controllers[current_tab]->GetCurrentProfile());
|
||||
|
||||
for (auto* controller : player_controllers) {
|
||||
controller->LoadProfile();
|
||||
controller->ApplyConfiguration();
|
||||
controller->TryDisconnectSelectedController();
|
||||
}
|
||||
@@ -195,6 +205,7 @@ void ConfigureInput::ApplyConfiguration() {
|
||||
for (auto* controller : player_controllers) {
|
||||
controller->TryConnectSelectedController();
|
||||
}
|
||||
profiles->SaveAllProfiles();
|
||||
|
||||
advanced->ApplyConfiguration();
|
||||
|
||||
@@ -273,12 +284,28 @@ void ConfigureInput::UpdateAllInputDevices() {
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigureInput::UpdateAllInputProfiles(std::size_t player_index) {
|
||||
for (std::size_t i = 0; i < player_controllers.size(); ++i) {
|
||||
if (i == player_index) {
|
||||
continue;
|
||||
}
|
||||
|
||||
player_controllers[i]->UpdateInputProfiles();
|
||||
void ConfigureInput::UpdateAllInputProfiles() {
|
||||
for (const auto& player : player_controllers) {
|
||||
player->UpdateInputProfiles();
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigureInput::LoadAllProfiles() {
|
||||
for (const auto& player : player_controllers) {
|
||||
player->LoadProfile();
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigureInput::RenameInputProfile(const QString& old_name, const QString& new_name) {
|
||||
for (const auto& player : player_controllers) {
|
||||
player->RenameSpecifiedProfile(old_name.toStdString(), new_name.toStdString());
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigureInput::TabWindowChanged(std::size_t new_tab) {
|
||||
player_controllers[current_tab]->SaveProfile(
|
||||
player_controllers[current_tab]->GetCurrentProfile());
|
||||
player_controllers[new_tab]->LoadProfile();
|
||||
|
||||
current_tab = new_tab;
|
||||
}
|
||||
|
||||
@@ -52,7 +52,10 @@ private:
|
||||
|
||||
void UpdateDockedState(bool is_handheld);
|
||||
void UpdateAllInputDevices();
|
||||
void UpdateAllInputProfiles(std::size_t player_index);
|
||||
void UpdateAllInputProfiles();
|
||||
void LoadAllProfiles();
|
||||
void RenameInputProfile(const QString& old_name, const QString& new_name);
|
||||
void TabWindowChanged(std::size_t new_tab);
|
||||
|
||||
/// Load configuration settings.
|
||||
void LoadConfiguration();
|
||||
@@ -64,6 +67,7 @@ private:
|
||||
std::unique_ptr<Ui::ConfigureInput> ui;
|
||||
|
||||
std::unique_ptr<InputProfiles> profiles;
|
||||
std::size_t current_tab = 0;
|
||||
|
||||
std::array<ConfigureInputPlayer*, 8> player_controllers;
|
||||
std::array<QWidget*, 8> player_tabs;
|
||||
|
||||
@@ -542,12 +542,12 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
|
||||
|
||||
connect(ui->buttonProfilesNew, &QPushButton::clicked, this,
|
||||
&ConfigureInputPlayer::CreateProfile);
|
||||
connect(ui->buttonProfilesRename, &QPushButton::clicked, this,
|
||||
&ConfigureInputPlayer::RenameProfile);
|
||||
connect(ui->buttonProfilesDelete, &QPushButton::clicked, this,
|
||||
&ConfigureInputPlayer::DeleteProfile);
|
||||
connect(ui->comboProfiles, qOverload<int>(&QComboBox::activated), this,
|
||||
&ConfigureInputPlayer::LoadProfile);
|
||||
connect(ui->buttonProfilesSave, &QPushButton::clicked, this,
|
||||
&ConfigureInputPlayer::SaveProfile);
|
||||
&ConfigureInputPlayer::ProfileChanged);
|
||||
|
||||
LoadConfiguration();
|
||||
|
||||
@@ -571,6 +571,8 @@ void ConfigureInputPlayer::ApplyConfiguration() {
|
||||
return;
|
||||
}
|
||||
|
||||
player.input_profile = current_profile;
|
||||
|
||||
auto& motions = player.motions;
|
||||
|
||||
std::transform(motions_param.begin(), motions_param.end(), motions.begin(),
|
||||
@@ -637,6 +639,7 @@ void ConfigureInputPlayer::showEvent(QShowEvent* event) {
|
||||
}
|
||||
QWidget::showEvent(event);
|
||||
ui->main->addWidget(bottom_row);
|
||||
emit PlayerTabSelected(player_index);
|
||||
}
|
||||
|
||||
void ConfigureInputPlayer::changeEvent(QEvent* event) {
|
||||
@@ -681,6 +684,13 @@ void ConfigureInputPlayer::LoadConfiguration() {
|
||||
ui->groupConnectedController->setChecked(
|
||||
player.connected ||
|
||||
(player_index == 0 && Settings::values.players.GetValue()[HANDHELD_INDEX].connected));
|
||||
|
||||
current_profile = player.input_profile;
|
||||
if (!profiles->ProfileExistsInMap(current_profile)) {
|
||||
current_profile = unselected_profile;
|
||||
}
|
||||
ui->comboProfiles->setCurrentText(QString::fromStdString(current_profile));
|
||||
LoadProfile();
|
||||
}
|
||||
|
||||
void ConfigureInputPlayer::ConnectPlayer(bool connected) {
|
||||
@@ -1223,9 +1233,13 @@ void ConfigureInputPlayer::keyPressEvent(QKeyEvent* event) {
|
||||
SetPollingResult({}, true);
|
||||
}
|
||||
|
||||
std::string ConfigureInputPlayer::GetCurrentProfile() const {
|
||||
return current_profile;
|
||||
}
|
||||
|
||||
void ConfigureInputPlayer::CreateProfile() {
|
||||
const auto profile_name =
|
||||
LimitableInputDialog::GetText(this, tr("New Profile"), tr("Enter a profile name:"), 1, 20);
|
||||
const auto profile_name = LimitableInputDialog::GetText(this, tr("Create Input Profile"),
|
||||
tr("Enter a profile name:"), 1, 20);
|
||||
|
||||
if (profile_name.isEmpty()) {
|
||||
return;
|
||||
@@ -1237,87 +1251,123 @@ void ConfigureInputPlayer::CreateProfile() {
|
||||
return;
|
||||
}
|
||||
|
||||
ApplyConfiguration();
|
||||
|
||||
if (!profiles->CreateProfile(profile_name.toStdString(), player_index)) {
|
||||
QMessageBox::critical(this, tr("Create Input Profile"),
|
||||
tr("Failed to create the input profile \"%1\"").arg(profile_name));
|
||||
UpdateInputProfiles();
|
||||
emit RefreshInputProfiles(player_index);
|
||||
if (profiles->ProfileExistsInMap(profile_name.toStdString())) {
|
||||
QMessageBox::critical(this, tr("Create Input Profile"), tr("This profile already exists!"));
|
||||
return;
|
||||
}
|
||||
|
||||
emit RefreshInputProfiles(player_index);
|
||||
|
||||
ui->comboProfiles->addItem(profile_name);
|
||||
ui->comboProfiles->setCurrentIndex(ui->comboProfiles->count() - 1);
|
||||
SaveProfile(current_profile);
|
||||
current_profile = profile_name.toStdString();
|
||||
SaveProfile(current_profile);
|
||||
emit RefreshInputProfiles();
|
||||
}
|
||||
|
||||
void ConfigureInputPlayer::DeleteProfile() {
|
||||
const QString profile_name = ui->comboProfiles->itemText(ui->comboProfiles->currentIndex());
|
||||
|
||||
if (profile_name.isEmpty()) {
|
||||
if (ui->comboProfiles->currentIndex() <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!profiles->DeleteProfile(profile_name.toStdString())) {
|
||||
QMessageBox::critical(this, tr("Delete Input Profile"),
|
||||
tr("Failed to delete the input profile \"%1\"").arg(profile_name));
|
||||
UpdateInputProfiles();
|
||||
emit RefreshInputProfiles(player_index);
|
||||
return;
|
||||
}
|
||||
|
||||
emit RefreshInputProfiles(player_index);
|
||||
|
||||
ui->comboProfiles->removeItem(ui->comboProfiles->currentIndex());
|
||||
ui->comboProfiles->setCurrentIndex(-1);
|
||||
SaveProfile(current_profile);
|
||||
emit InputProfileDeleted();
|
||||
profiles->map_profiles.erase(current_profile);
|
||||
emit RefreshInputProfiles();
|
||||
}
|
||||
|
||||
void ConfigureInputPlayer::LoadProfile() {
|
||||
const QString profile_name = ui->comboProfiles->itemText(ui->comboProfiles->currentIndex());
|
||||
|
||||
if (profile_name.isEmpty()) {
|
||||
if (ui->comboProfiles->currentIndex() <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
ApplyConfiguration();
|
||||
const QString profile_name = ui->comboProfiles->currentText();
|
||||
Settings::InputProfile& profile = profiles->map_profiles[profile_name.toStdString()];
|
||||
|
||||
if (!profiles->LoadProfile(profile_name.toStdString(), player_index)) {
|
||||
QMessageBox::critical(this, tr("Load Input Profile"),
|
||||
tr("Failed to load the input profile \"%1\"").arg(profile_name));
|
||||
UpdateInputProfiles();
|
||||
emit RefreshInputProfiles(player_index);
|
||||
return;
|
||||
}
|
||||
ui->comboControllerType->setCurrentIndex(GetIndexFromControllerType(profile.controller_type));
|
||||
std::transform(profile.buttons.begin(), profile.buttons.end(), buttons_param.begin(),
|
||||
[](const std::string& str) { return Common::ParamPackage(str); });
|
||||
std::transform(profile.analogs.begin(), profile.analogs.end(), analogs_param.begin(),
|
||||
[](const std::string& str) { return Common::ParamPackage(str); });
|
||||
std::transform(profile.motions.begin(), profile.motions.end(), motions_param.begin(),
|
||||
[](const std::string& str) { return Common::ParamPackage(str); });
|
||||
|
||||
LoadConfiguration();
|
||||
UpdateUI();
|
||||
UpdateInputDeviceCombobox();
|
||||
}
|
||||
|
||||
void ConfigureInputPlayer::SaveProfile() {
|
||||
const QString profile_name = ui->comboProfiles->itemText(ui->comboProfiles->currentIndex());
|
||||
void ConfigureInputPlayer::SaveProfile(const std::string& profile_name) {
|
||||
if (profile_name.empty() || profile_name == unselected_profile) {
|
||||
return;
|
||||
}
|
||||
|
||||
Settings::InputProfile profile;
|
||||
|
||||
profile.controller_type = GetControllerTypeFromIndex(ui->comboControllerType->currentIndex());
|
||||
std::transform(buttons_param.begin(), buttons_param.end(), profile.buttons.begin(),
|
||||
[](const Common::ParamPackage& param) { return param.Serialize(); });
|
||||
std::transform(analogs_param.begin(), analogs_param.end(), profile.analogs.begin(),
|
||||
[](const Common::ParamPackage& param) { return param.Serialize(); });
|
||||
std::transform(motions_param.begin(), motions_param.end(), profile.motions.begin(),
|
||||
[](const Common::ParamPackage& param) { return param.Serialize(); });
|
||||
|
||||
profiles->map_profiles.insert_or_assign(profile_name, profile);
|
||||
}
|
||||
|
||||
void ConfigureInputPlayer::RenameProfile() {
|
||||
if (ui->comboProfiles->currentIndex() <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto profile_name = LimitableInputDialog::GetText(
|
||||
this, tr("Rename Input Profile"), tr("Enter the new profile name:"), 1, 20);
|
||||
|
||||
if (profile_name.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ApplyConfiguration();
|
||||
|
||||
if (!profiles->SaveProfile(profile_name.toStdString(), player_index)) {
|
||||
QMessageBox::critical(this, tr("Save Input Profile"),
|
||||
tr("Failed to save the input profile \"%1\"").arg(profile_name));
|
||||
UpdateInputProfiles();
|
||||
emit RefreshInputProfiles(player_index);
|
||||
if (!InputProfiles::IsProfileNameValid(profile_name.toStdString())) {
|
||||
QMessageBox::critical(this, tr("Rename Input Profile"),
|
||||
tr("The given profile name is not valid!"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (profiles->ProfileExistsInMap(profile_name.toStdString())) {
|
||||
QMessageBox::critical(this, tr("Rename Input Profile"), tr("This profile already exists!"));
|
||||
return;
|
||||
}
|
||||
|
||||
profiles->map_profiles.insert_or_assign(profile_name.toStdString(),
|
||||
profiles->map_profiles[current_profile]);
|
||||
profiles->map_profiles.erase(current_profile);
|
||||
emit InputProfileRenamed(QString::fromStdString(current_profile), profile_name);
|
||||
}
|
||||
|
||||
void ConfigureInputPlayer::ProfileChanged() {
|
||||
// The input profile combobox will have the new profile selected, so save the previous one which
|
||||
// is stored in current_profile.
|
||||
SaveProfile(current_profile);
|
||||
LoadProfile();
|
||||
|
||||
current_profile = ui->comboProfiles->currentText().toStdString();
|
||||
}
|
||||
|
||||
void ConfigureInputPlayer::UpdateInputProfiles() {
|
||||
ui->comboProfiles->clear();
|
||||
|
||||
ui->comboProfiles->addItem(QString::fromStdString(unselected_profile));
|
||||
for (const auto& profile_name : profiles->GetInputProfileNames()) {
|
||||
ui->comboProfiles->addItem(QString::fromStdString(profile_name));
|
||||
}
|
||||
|
||||
ui->comboProfiles->setCurrentIndex(-1);
|
||||
if (ui->comboProfiles->findText(QString::fromStdString(current_profile)) < 0) {
|
||||
current_profile = unselected_profile;
|
||||
}
|
||||
ui->comboProfiles->setCurrentText(QString::fromStdString(current_profile));
|
||||
}
|
||||
|
||||
void ConfigureInputPlayer::RenameSpecifiedProfile(const std::string& old_name,
|
||||
const std::string& new_name) {
|
||||
if (current_profile == old_name) {
|
||||
current_profile = new_name;
|
||||
}
|
||||
|
||||
UpdateInputProfiles();
|
||||
}
|
||||
|
||||
@@ -75,6 +75,18 @@ public:
|
||||
/// Updates the list of controller profiles.
|
||||
void UpdateInputProfiles();
|
||||
|
||||
/// Renames the specified input profile.
|
||||
void RenameSpecifiedProfile(const std::string& old_name, const std::string& new_name);
|
||||
|
||||
/// Returns the current profile.
|
||||
std::string GetCurrentProfile() const;
|
||||
|
||||
/// Loads the selected controller profile.
|
||||
void LoadProfile();
|
||||
|
||||
/// Saves the current controller configuration into a selected controller profile.
|
||||
void SaveProfile(const std::string& profile_name);
|
||||
|
||||
/// Restore all buttons to their default values.
|
||||
void RestoreDefaults();
|
||||
|
||||
@@ -88,12 +100,14 @@ signals:
|
||||
void HandheldStateChanged(bool is_handheld);
|
||||
/// Emitted when the input devices combobox is being refreshed.
|
||||
void RefreshInputDevices();
|
||||
/**
|
||||
* Emitted when the input profiles combobox is being refreshed.
|
||||
* The player_index represents the current player's index, and the profile combobox
|
||||
* will not be updated for this index as they are already updated by other mechanisms.
|
||||
*/
|
||||
void RefreshInputProfiles(std::size_t player_index);
|
||||
/// Emitted when the input profiles combobox is being refreshed.
|
||||
void RefreshInputProfiles();
|
||||
/// Emitted when an input profile has been deleted.
|
||||
void InputProfileDeleted();
|
||||
/// Emitted when an input profile has been renamed.
|
||||
void InputProfileRenamed(QString old_name, QString new_name);
|
||||
/// Emitted when a new player tab is selected.
|
||||
void PlayerTabSelected(std::size_t player_index);
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent* event) override;
|
||||
@@ -155,11 +169,11 @@ private:
|
||||
/// Deletes the selected controller profile.
|
||||
void DeleteProfile();
|
||||
|
||||
/// Loads the selected controller profile.
|
||||
void LoadProfile();
|
||||
/// Renames the selected input profile.
|
||||
void RenameProfile();
|
||||
|
||||
/// Saves the current controller configuration into a selected controller profile.
|
||||
void SaveProfile();
|
||||
/// Saves the previous controller profile and then loads the new one selected.
|
||||
void ProfileChanged();
|
||||
|
||||
std::unique_ptr<Ui::ConfigureInputPlayer> ui;
|
||||
|
||||
@@ -169,6 +183,8 @@ private:
|
||||
InputCommon::InputSubsystem* input_subsystem;
|
||||
|
||||
InputProfiles* profiles;
|
||||
std::string current_profile;
|
||||
const std::string unselected_profile = "[none]";
|
||||
|
||||
std::unique_ptr<QTimer> timeout_timer;
|
||||
std::unique_ptr<QTimer> poll_timer;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>780</width>
|
||||
<width>923</width>
|
||||
<height>487</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -219,22 +219,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonProfilesSave">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>68</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">min-width: 68px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonProfilesNew">
|
||||
<property name="maximumSize">
|
||||
@@ -251,6 +235,22 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonProfilesRename">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>68</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">min-width: 68px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Rename</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonProfilesDelete">
|
||||
<property name="maximumSize">
|
||||
@@ -412,7 +412,7 @@
|
||||
<widget class="QPushButton" name="buttonLStickUp">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>68</width>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -482,7 +482,7 @@
|
||||
<widget class="QPushButton" name="buttonLStickLeft">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>68</width>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -531,7 +531,7 @@
|
||||
<widget class="QPushButton" name="buttonLStickRight">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>68</width>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -613,7 +613,7 @@
|
||||
<widget class="QPushButton" name="buttonLStickDown">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>68</width>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -683,7 +683,7 @@
|
||||
<widget class="QPushButton" name="buttonLStick">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>68</width>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -732,7 +732,7 @@
|
||||
<widget class="QPushButton" name="buttonLStickMod">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>68</width>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -985,7 +985,7 @@
|
||||
<widget class="QPushButton" name="buttonDpadUp">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>68</width>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -1055,7 +1055,7 @@
|
||||
<widget class="QPushButton" name="buttonDpadLeft">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>68</width>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -1104,7 +1104,7 @@
|
||||
<widget class="QPushButton" name="buttonDpadRight">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>68</width>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -1186,7 +1186,7 @@
|
||||
<widget class="QPushButton" name="buttonDpadDown">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>68</width>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -1311,7 +1311,7 @@
|
||||
<widget class="QPushButton" name="buttonL">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>68</width>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -1360,7 +1360,7 @@
|
||||
<widget class="QPushButton" name="buttonZL">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>68</width>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -1464,7 +1464,7 @@
|
||||
<widget class="QPushButton" name="buttonMinus">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>68</width>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -1513,7 +1513,7 @@
|
||||
<widget class="QPushButton" name="buttonScreenshot">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>68</width>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -1583,7 +1583,7 @@
|
||||
<widget class="QPushButton" name="buttonPlus">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>68</width>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -1632,7 +1632,7 @@
|
||||
<widget class="QPushButton" name="buttonHome">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>68</width>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -1736,7 +1736,7 @@
|
||||
<widget class="QPushButton" name="buttonR">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>68</width>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -1785,7 +1785,7 @@
|
||||
<widget class="QPushButton" name="buttonZR">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>68</width>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -1889,7 +1889,7 @@
|
||||
<widget class="QPushButton" name="buttonSL">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>68</width>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -1938,7 +1938,7 @@
|
||||
<widget class="QPushButton" name="buttonSR">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>68</width>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -2046,7 +2046,7 @@
|
||||
<widget class="QPushButton" name="buttonMotionLeft">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>68</width>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -2095,7 +2095,7 @@
|
||||
<widget class="QPushButton" name="buttonMotionRight">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>68</width>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -2244,7 +2244,7 @@
|
||||
<widget class="QPushButton" name="buttonX">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>68</width>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -2314,7 +2314,7 @@
|
||||
<widget class="QPushButton" name="buttonY">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>68</width>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -2363,7 +2363,7 @@
|
||||
<widget class="QPushButton" name="buttonA">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>68</width>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -2445,7 +2445,7 @@
|
||||
<widget class="QPushButton" name="buttonB">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>68</width>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -2599,7 +2599,7 @@
|
||||
<widget class="QPushButton" name="buttonRStickUp">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>68</width>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -2669,7 +2669,7 @@
|
||||
<widget class="QPushButton" name="buttonRStickLeft">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>68</width>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -2718,7 +2718,7 @@
|
||||
<widget class="QPushButton" name="buttonRStickRight">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>68</width>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -2800,7 +2800,7 @@
|
||||
<widget class="QPushButton" name="buttonRStickDown">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>68</width>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -2870,7 +2870,7 @@
|
||||
<widget class="QPushButton" name="buttonRStick">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>68</width>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -2919,7 +2919,7 @@
|
||||
<widget class="QPushButton" name="buttonRStickMod">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>68</width>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
|
||||
@@ -48,13 +48,20 @@ InputProfiles::InputProfiles() {
|
||||
nullptr, input_profile_loc,
|
||||
[this](u64* entries_out, const std::string& directory, const std::string& filename) {
|
||||
if (IsINI(filename) && IsProfileNameValid(GetNameWithoutExtension(filename))) {
|
||||
map_profiles.insert_or_assign(
|
||||
map_profiles_old.insert_or_assign(
|
||||
GetNameWithoutExtension(filename),
|
||||
std::make_unique<Config>(GetNameWithoutExtension(filename),
|
||||
Config::ConfigType::InputProfile));
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
for (const auto& profile : map_profiles_old) {
|
||||
Settings::InputProfile new_profile;
|
||||
profile.second->ReadToProfileStruct(new_profile);
|
||||
|
||||
map_profiles.insert_or_assign(profile.first, new_profile);
|
||||
}
|
||||
}
|
||||
|
||||
InputProfiles::~InputProfiles() = default;
|
||||
@@ -63,13 +70,8 @@ std::vector<std::string> InputProfiles::GetInputProfileNames() {
|
||||
std::vector<std::string> profile_names;
|
||||
profile_names.reserve(map_profiles.size());
|
||||
|
||||
for (const auto& [profile_name, config] : map_profiles) {
|
||||
if (!ProfileExistsInFilesystem(profile_name)) {
|
||||
DeleteProfile(profile_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
profile_names.push_back(profile_name);
|
||||
for (const auto& profile : map_profiles) {
|
||||
profile_names.push_back(profile.first);
|
||||
}
|
||||
|
||||
return profile_names;
|
||||
@@ -79,53 +81,21 @@ bool InputProfiles::IsProfileNameValid(std::string_view profile_name) {
|
||||
return profile_name.find_first_of("<>:;\"/\\|,.!?*") == std::string::npos;
|
||||
}
|
||||
|
||||
bool InputProfiles::CreateProfile(const std::string& profile_name, std::size_t player_index) {
|
||||
if (ProfileExistsInMap(profile_name)) {
|
||||
return false;
|
||||
void InputProfiles::SaveAllProfiles() {
|
||||
for (const auto& old_profile : map_profiles_old) {
|
||||
if (!map_profiles.contains(old_profile.first)) {
|
||||
FS::Delete(old_profile.second->GetConfigFilePath());
|
||||
}
|
||||
}
|
||||
|
||||
map_profiles.insert_or_assign(
|
||||
profile_name, std::make_unique<Config>(profile_name, Config::ConfigType::InputProfile));
|
||||
for (const auto& profile : map_profiles) {
|
||||
const auto& config_profile =
|
||||
std::make_unique<Config>(profile.first, Config::ConfigType::InputProfile);
|
||||
|
||||
return SaveProfile(profile_name, player_index);
|
||||
}
|
||||
|
||||
bool InputProfiles::DeleteProfile(const std::string& profile_name) {
|
||||
if (!ProfileExistsInMap(profile_name)) {
|
||||
return false;
|
||||
config_profile->WriteFromProfileStruct(profile.second);
|
||||
}
|
||||
|
||||
if (!ProfileExistsInFilesystem(profile_name) ||
|
||||
FS::Delete(map_profiles[profile_name]->GetConfigFilePath())) {
|
||||
map_profiles.erase(profile_name);
|
||||
}
|
||||
|
||||
return !ProfileExistsInMap(profile_name) && !ProfileExistsInFilesystem(profile_name);
|
||||
}
|
||||
|
||||
bool InputProfiles::LoadProfile(const std::string& profile_name, std::size_t player_index) {
|
||||
if (!ProfileExistsInMap(profile_name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ProfileExistsInFilesystem(profile_name)) {
|
||||
map_profiles.erase(profile_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
map_profiles[profile_name]->ReadControlPlayerValue(player_index);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InputProfiles::SaveProfile(const std::string& profile_name, std::size_t player_index) {
|
||||
if (!ProfileExistsInMap(profile_name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
map_profiles[profile_name]->SaveControlPlayerValue(player_index);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InputProfiles::ProfileExistsInMap(const std::string& profile_name) const {
|
||||
return map_profiles.find(profile_name) != map_profiles.end();
|
||||
return map_profiles.contains(profile_name);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "core/settings.h"
|
||||
|
||||
class Config;
|
||||
|
||||
class InputProfiles {
|
||||
@@ -16,17 +18,15 @@ public:
|
||||
explicit InputProfiles();
|
||||
virtual ~InputProfiles();
|
||||
|
||||
std::unordered_map<std::string, Settings::InputProfile> map_profiles;
|
||||
|
||||
std::vector<std::string> GetInputProfileNames();
|
||||
|
||||
bool ProfileExistsInMap(const std::string& profile_name) const;
|
||||
static bool IsProfileNameValid(std::string_view profile_name);
|
||||
|
||||
bool CreateProfile(const std::string& profile_name, std::size_t player_index);
|
||||
bool DeleteProfile(const std::string& profile_name);
|
||||
bool LoadProfile(const std::string& profile_name, std::size_t player_index);
|
||||
bool SaveProfile(const std::string& profile_name, std::size_t player_index);
|
||||
void SaveAllProfiles();
|
||||
|
||||
private:
|
||||
bool ProfileExistsInMap(const std::string& profile_name) const;
|
||||
|
||||
std::unordered_map<std::string, std::unique_ptr<Config>> map_profiles;
|
||||
std::unordered_map<std::string, std::unique_ptr<Config>> map_profiles_old;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user