This commit is contained in:
iTrooz 2025-12-15 22:54:35 +01:00 committed by GitHub
commit a98bd520e0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 116 additions and 10 deletions

View File

@ -352,6 +352,33 @@ bool IniFile::Save(const std::string& filename)
return File::RenameSync(temp, filename);
}
bool IniFile::CompareValues(IniFile& other) const
{
if (sections.size() != other.sections.size())
return false;
for (const Section& s : sections)
{
const Section* os = other.GetSection(s.name);
if (!os)
return false;
if (s.values.size() != os->values.size())
return false;
for (const auto& [key, val] : s.values)
{
const auto it = os->values.find(key);
if (it == os->values.end())
return false;
if (it->second != val)
return false;
}
}
return true;
}
// Unit test. TODO: Move to the real unit test framework.
/*
int main()

View File

@ -81,6 +81,8 @@ public:
IniFile();
~IniFile();
bool CompareValues(IniFile& other) const;
/**
* Loads sections and keys.
* @param filename filename of the ini file which should be loaded

View File

@ -770,6 +770,9 @@ void IOWindow::UpdateExpression(std::string new_expression, UpdateMode mode)
const auto status = m_reference->GetParseStatus();
m_controller->UpdateSingleControlReference(g_controller_interface, m_reference);
// Emit signal that this IOWindow's expression changed.
emit OnMappingChange();
// This is the only place where we need to update the user variables. Keep the first 4 items.
while (m_variables_combo->count() > 4)
{

View File

@ -71,6 +71,7 @@ public:
signals:
void DetectInputComplete();
void TestOutputComplete();
void OnMappingChange();
private:
std::shared_ptr<ciface::Core::Device> GetSelectedDevice() const;

View File

@ -92,6 +92,9 @@ void MappingButton::AdvancedPressed()
IOWindow io(m_mapping_window, m_mapping_window->GetController(), m_reference,
m_reference->IsInput() ? IOWindow::Type::Input : IOWindow::Type::Output);
connect(&io, &IOWindow::OnMappingChange, [this] { m_mapping_window->OnMappingChange(); });
io.exec();
ConfigChanged();

View File

@ -133,6 +133,7 @@ public:
m_parent->GetController()->UpdateSingleControlReference(g_controller_interface,
control_reference);
m_parent->GetController()->GetConfig()->GenerateControllerTextures();
m_parent->OnMappingChange();
}
void UpdateInputDetectionStartTimer()

View File

@ -21,6 +21,7 @@ MappingDouble::MappingDouble(MappingWidget* parent, ControllerEmu::NumericSettin
connect(this, &QDoubleSpinBox::valueChanged, this, [this, parent](double value) {
m_setting.SetValue(value);
ConfigChanged();
parent->OnMappingChange();
parent->SaveSettings();
});
@ -83,6 +84,7 @@ MappingBool::MappingBool(MappingWidget* parent, ControllerEmu::NumericSetting<bo
#endif
m_setting.SetValue(value != 0);
ConfigChanged();
parent->OnMappingChange();
parent->SaveSettings();
});

View File

@ -392,6 +392,8 @@ MappingWidget::CreateSettingAdvancedMappingButton(ControllerEmu::NumericSettingB
ConfigChanged();
IOWindow io(GetParent(), GetController(), &setting.GetInputReference(), IOWindow::Type::Input);
connect(&io, &IOWindow::OnMappingChange, [this] { OnMappingChange(); });
io.exec();
setting.SimplifyIfPossible();
@ -402,3 +404,8 @@ MappingWidget::CreateSettingAdvancedMappingButton(ControllerEmu::NumericSettingB
return button;
}
void MappingWidget::OnMappingChange()
{
this->m_parent->OnMappingChange();
}

View File

@ -37,6 +37,8 @@ public:
virtual void SaveSettings() = 0;
virtual InputConfig* GetConfig() = 0;
void OnMappingChange();
signals:
void Update();
void ConfigChanged();

View File

@ -211,6 +211,7 @@ void MappingWindow::ConnectWidgets()
{
connect(&Settings::Instance(), &Settings::DevicesChanged, this, &MappingWindow::ConfigChanged);
connect(this, &MappingWindow::ConfigChanged, this, &MappingWindow::UpdateDeviceList);
connect(this, &MappingWindow::ConfigChanged, this, &MappingWindow::OnMappingChange);
connect(m_devices_combo, &QComboBox::currentIndexChanged, this, &MappingWindow::OnSelectDevice);
connect(m_reset_clear, &QPushButton::clicked, this, &MappingWindow::OnClearFieldsPressed);
@ -221,7 +222,7 @@ void MappingWindow::ConnectWidgets()
connect(m_profiles_open_folder, &QAction::triggered, this, &MappingWindow::OnOpenProfileFolder);
connect(m_profiles_combo, &QComboBox::currentIndexChanged, this, &MappingWindow::OnSelectProfile);
connect(m_profiles_combo, &QComboBox::editTextChanged, this,
connect(m_profiles_combo, &QComboBox::currentTextChanged, this,
&MappingWindow::OnProfileTextChanged);
// We currently use the "Close" button as an "Accept" button so we must save on reject.
@ -245,19 +246,66 @@ void MappingWindow::UpdateProfileIndex()
void MappingWindow::UpdateProfileButtonState()
{
// Make sure save/delete buttons are disabled for built-in profiles
// currentData() is not up to date on a currentTextChanged() event, so find profile path from
// currentText() (which is up to date)
const int index = m_profiles_combo->findText(m_profiles_combo->currentText());
QString profile_path;
if (index != -1)
profile_path = m_profiles_combo->itemData(index).toString();
bool builtin = false;
if (m_profiles_combo->findText(m_profiles_combo->currentText()) != -1)
// Init new buttons state (enabled by default)
bool load_enabled = true;
bool save_enabled = true;
bool delete_enabled = true;
QString load_tooltip;
QString save_tooltip;
QString delete_tooltip;
// Check if mapping is modified
// Load memory mapping
Common::IniFile memoryIni;
m_controller->SaveConfig(memoryIni.GetOrCreateSection("Profile"));
// Load disk mapping
Common::IniFile diskIni;
diskIni.Load(profile_path.toStdString());
// Pass the disk mapping through the controller to normalize it
m_controller->LoadConfig(diskIni.GetOrCreateSection("Profile"));
m_controller->SaveConfig(diskIni.GetOrCreateSection("Profile"));
// Restore controller mapping from memory
m_controller->LoadConfig(memoryIni.GetOrCreateSection("Profile"));
// Compare mappings
bool mapping_is_the_same = diskIni.CompareValues(memoryIni);
if (mapping_is_the_same)
{
const QString profile_path = m_profiles_combo->currentData().toString();
std::string sys_dir = File::GetSysDirectory();
sys_dir = ReplaceAll(sys_dir, "\\", DIR_SEP);
builtin = profile_path.startsWith(QString::fromStdString(sys_dir));
load_enabled = false;
load_tooltip =
tr("Cannot do this action. Reason: No changes between profile file and current mappings");
save_enabled = false;
save_tooltip =
tr("Cannot do this action. Reason: No changes between profile file and current mappings");
}
m_profiles_save->setEnabled(!builtin);
m_profiles_delete->setEnabled(!builtin);
// Make sure save/delete buttons are disabled for built-in profiles
std::string sys_dir = File::GetSysDirectory();
sys_dir = ReplaceAll(sys_dir, "\\", DIR_SEP);
bool builtin = profile_path.startsWith(QString::fromStdString(sys_dir));
if (builtin)
{
save_enabled = false;
delete_enabled = false;
save_tooltip = tr("Cannot do this action. Reason: Built-in profile");
delete_tooltip = tr("Cannot do this action. Reason: Built-in profile");
}
// Update buttons state
m_profiles_load->setEnabled(load_enabled);
m_profiles_load->setToolTip(load_tooltip);
m_profiles_save->setEnabled(save_enabled);
m_profiles_save->setToolTip(save_tooltip);
m_profiles_delete->setEnabled(delete_enabled);
m_profiles_delete->setToolTip(delete_tooltip);
}
void MappingWindow::OnSelectProfile(int)
@ -335,6 +383,8 @@ void MappingWindow::OnLoadProfilePressed()
m_controller->UpdateReferences(g_controller_interface);
m_controller->GetConfig()->GenerateControllerTextures();
UpdateProfileButtonState();
const auto lock = GetController()->GetStateLock();
emit ConfigChanged();
}
@ -356,6 +406,8 @@ void MappingWindow::OnSaveProfilePressed()
m_controller->SaveConfig(ini.GetOrCreateSection("Profile"));
ini.Save(profile_path);
UpdateProfileButtonState();
if (m_profiles_combo->findText(profile_name) == -1)
{
PopulateProfileSelection();
@ -624,3 +676,8 @@ void MappingWindow::ActivateExtensionTab()
{
m_tab_widget->setCurrentIndex(3);
}
void MappingWindow::OnMappingChange()
{
UpdateProfileButtonState();
}

View File

@ -56,6 +56,7 @@ public:
bool IsIterativeMappingEnabled() const;
void ShowExtensionMotionTabs(bool show);
void ActivateExtensionTab();
void OnMappingChange();
signals:
// Emitted when config has changed so widgets can update to reflect the change.