Skip to content

Commit

Permalink
Merge pull request #11300 from acolombier/feat/controller-custom-sett…
Browse files Browse the repository at this point in the history
…ings

feat(Controller): add support for settings
  • Loading branch information
daschuer authored Mar 28, 2024
2 parents 0c34f90 + d72e012 commit 99406cb
Show file tree
Hide file tree
Showing 23 changed files with 2,047 additions and 155 deletions.
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -731,10 +731,14 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL
src/controllers/controllerlearningeventfilter.cpp
src/controllers/controllermanager.cpp
src/controllers/controllermappinginfo.cpp
src/controllers/legacycontrollersettings.cpp
src/controllers/legacycontrollersettingslayout.cpp
src/controllers/controllermappinginfoenumerator.cpp
src/controllers/controllermappingtablemodel.cpp
src/controllers/controlleroutputmappingtablemodel.cpp
src/controllers/controlpickermenu.cpp
src/controllers/legacycontrollermappingfilehandler.cpp
src/controllers/legacycontrollermapping.cpp
src/controllers/delegates/controldelegate.cpp
src/controllers/delegates/midibytedelegate.cpp
src/controllers/delegates/midichanneldelegate.cpp
Expand Down Expand Up @@ -2070,6 +2074,7 @@ add_executable(mixxx-test
src/test/colorpalette_test.cpp
src/test/configobject_test.cpp
src/test/controller_mapping_validation_test.cpp
src/test/controller_mapping_settings_test.cpp
src/test/controllerscriptenginelegacy_test.cpp
src/test/controlobjecttest.cpp
src/test/controlobjectaliastest.cpp
Expand Down
10 changes: 10 additions & 0 deletions res/controllers/engine-api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,16 @@ declare interface ScriptConnection {
/** ControllerScriptInterfaceLegacy */

declare namespace engine {
type SettingValue = string | number | boolean;
/**
* Gets the value of a controller setting
* The value is either set in the preferences dialog,
* or got restored from file.
* @param name Name of the setting (as specified in the XML file of the mapping)
* @returns Value of the setting, or undefined in failure case
*/
function getSetting(name: string): SettingValue | undefined;

/**
* Gets the control value
*
Expand Down
2 changes: 2 additions & 0 deletions src/controllers/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ bool Controller::applyMapping() {
}

m_pScriptEngineLegacy->setScriptFiles(scriptFiles);

m_pScriptEngineLegacy->setSettings(pMapping->getSettings());
return m_pScriptEngineLegacy->initialize();
}

Expand Down
1 change: 1 addition & 0 deletions src/controllers/controllermanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ void ControllerManager::slotSetUpDevices() {
if (!pMapping) {
continue;
}
pMapping->loadSettings(m_pConfig, pController->getName());

// This runs on the main thread but LegacyControllerMapping is not thread safe, so clone it.
pController->setMapping(pMapping->clone());
Expand Down
79 changes: 63 additions & 16 deletions src/controllers/dlgprefcontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "moc_dlgprefcontroller.cpp"
#include "preferences/usersettings.h"
#include "util/desktophelper.h"
#include "util/parented_ptr.h"
#include "util/string.h"

namespace {
Expand Down Expand Up @@ -410,6 +411,7 @@ QString DlgPrefController::mappingFileLinks(

void DlgPrefController::enumerateMappings(const QString& selectedMappingPath) {
m_ui.comboBoxMapping->blockSignals(true);
QString currentMappingFilePath = mappingFilePathFromIndex(m_ui.comboBoxMapping->currentIndex());
m_ui.comboBoxMapping->clear();

// qDebug() << "Enumerating mappings for controller" << m_pController->getName();
Expand Down Expand Up @@ -461,14 +463,18 @@ void DlgPrefController::enumerateMappings(const QString& selectedMappingPath) {
} else if (match.isValid()) {
index = m_ui.comboBoxMapping->findText(match.getName());
}
QString newMappingFilePath = mappingFilePathFromIndex(index);
if (index == -1) {
m_ui.chkEnabledDevice->setEnabled(false);
m_ui.groupBoxSettings->setVisible(false);
} else {
m_ui.comboBoxMapping->setCurrentIndex(index);
m_ui.chkEnabledDevice->setEnabled(true);
}
m_ui.comboBoxMapping->blockSignals(false);
slotMappingSelected(m_ui.comboBoxMapping->currentIndex());
if (newMappingFilePath != currentMappingFilePath) {
slotMappingSelected(index);
}
}

MappingInfo DlgPrefController::enumerateMappingsFromEnumerator(
Expand Down Expand Up @@ -498,6 +504,8 @@ MappingInfo DlgPrefController::enumerateMappingsFromEnumerator(
void DlgPrefController::slotUpdate() {
enumerateMappings(m_pControllerManager->getConfiguredMappingFileForDevice(
m_pController->getName()));
// Force updating the controller settings
slotMappingSelected(m_ui.comboBoxMapping->currentIndex());

// enumeratePresets calls slotPresetSelected which will check the m_ui.chkEnabledDevice
// checkbox if there is a valid mapping saved in the mixxx.cfg file. However, the
Expand All @@ -514,9 +522,10 @@ void DlgPrefController::slotUpdate() {
}

void DlgPrefController::slotResetToDefaults() {
m_ui.chkEnabledDevice->setChecked(false);
if (m_pMapping) {
m_pMapping->resetSettings();
}
enumerateMappings(QString());
slotMappingSelected(m_ui.comboBoxMapping->currentIndex());
}

void DlgPrefController::applyMappingChanges() {
Expand Down Expand Up @@ -557,9 +566,13 @@ void DlgPrefController::slotApply() {
return;
}

QString mappingPath = mappingPathFromIndex(m_ui.comboBoxMapping->currentIndex());
m_pMapping = LegacyControllerMappingFileHandler::loadMapping(
QFileInfo(mappingPath), QDir(resourceMappingsPath(m_pConfig)));
// If there is currently a mapping loaded, we save the new settings for it.
// Note that `m_pMapping`, `mappingFileInfo` and the setting on the screen
// will always match as the settings displayed are updated depending of the
// currently selected mapping in `slotMappingSelected`
if (m_pMapping) {
m_pMapping->saveSettings(m_pConfig, m_pController->getName());
}

// Load the resulting mapping (which has been mutated by the input/output
// table models). The controller clones the mapping so we aren't touching
Expand Down Expand Up @@ -593,7 +606,7 @@ void DlgPrefController::enableWizardAndIOTabs(bool enable) {
m_ui.outputMappingsTab->setEnabled(enable);
}

QString DlgPrefController::mappingPathFromIndex(int index) const {
QString DlgPrefController::mappingFilePathFromIndex(int index) const {
if (index == 0) {
// "No Mapping" item
return QString();
Expand All @@ -603,8 +616,8 @@ QString DlgPrefController::mappingPathFromIndex(int index) const {
}

void DlgPrefController::slotMappingSelected(int chosenIndex) {
QString mappingPath = mappingPathFromIndex(chosenIndex);
if (mappingPath.isEmpty()) { // User picked "No Mapping" item
QString mappingFilePath = mappingFilePathFromIndex(chosenIndex);
if (mappingFilePath.isEmpty()) { // User picked "No Mapping" item
m_ui.chkEnabledDevice->setEnabled(false);

if (m_ui.chkEnabledDevice->isChecked()) {
Expand All @@ -614,6 +627,8 @@ void DlgPrefController::slotMappingSelected(int chosenIndex) {
}
enableWizardAndIOTabs(false);
}

m_ui.groupBoxSettings->setVisible(false);
} else { // User picked a mapping
m_ui.chkEnabledDevice->setEnabled(true);

Expand All @@ -628,7 +643,7 @@ void DlgPrefController::slotMappingSelected(int chosenIndex) {
// Check if the mapping is different from the configured mapping
if (m_GuiInitialized &&
m_pControllerManager->getConfiguredMappingFileForDevice(
m_pController->getName()) != mappingPath) {
m_pController->getName()) != mappingFilePath) {
setDirty(true);
}

Expand All @@ -643,9 +658,10 @@ void DlgPrefController::slotMappingSelected(int chosenIndex) {
}
}

auto mappingFileInfo = QFileInfo(mappingFilePath);
std::shared_ptr<LegacyControllerMapping> pMapping =
LegacyControllerMappingFileHandler::loadMapping(
QFileInfo(mappingPath), QDir(resourceMappingsPath(m_pConfig)));
mappingFileInfo, QDir(resourceMappingsPath(m_pConfig)));

if (pMapping) {
DEBUG_ASSERT(!pMapping->isDirty());
Expand All @@ -654,7 +670,7 @@ void DlgPrefController::slotMappingSelected(int chosenIndex) {
if (previousMappingSaved) {
// We might have saved the previous preset with a new name, so update
// the preset combobox.
enumerateMappings(mappingPath);
enumerateMappings(mappingFilePath);
} else {
slotShowMapping(pMapping);
}
Expand Down Expand Up @@ -823,10 +839,41 @@ void DlgPrefController::slotShowMapping(std::shared_ptr<LegacyControllerMapping>
m_ui.labelLoadedMappingSupportLinks->setText(mappingSupportLinks(pMapping));
m_ui.labelLoadedMappingScriptFileLinks->setText(mappingFileLinks(pMapping));

// We mutate this mapping so keep a reference to it while we are using it.
// TODO(rryan): Clone it? Technically a waste since nothing else uses this
// copy but if someone did they might not expect it to change.
m_pMapping = pMapping;
if (pMapping) {
pMapping->loadSettings(m_pConfig, m_pController->getName());
auto settings = pMapping->getSettings();
auto* pLayout = pMapping->getSettingsLayout();

QLayoutItem* pItem;
while ((pItem = m_ui.groupBoxSettings->layout()->takeAt(0)) != nullptr) {
delete pItem->widget();
delete pItem;
}

if (pLayout != nullptr && !settings.isEmpty()) {
m_ui.groupBoxSettings->layout()->addWidget(pLayout->build(m_ui.groupBoxSettings));

for (const auto& setting : qAsConst(settings)) {
connect(setting.get(),
&AbstractLegacyControllerSetting::changed,
this,
[this] { setDirty(true); });
}
}

m_ui.groupBoxSettings->setVisible(!settings.isEmpty());
}

// If there is still settings that may be saved and no new mapping selected
// (e.g restored default), we keep the the dirty mapping live so it can be
// saved in apply slot. If there is a new mapping, then setting changes are
// discarded
if (pMapping || (m_pMapping && !m_pMapping->hasDirtySettings())) {
// We mutate this mapping so keep a reference to it while we are using it.
// TODO(rryan): Clone it? Technically a waste since nothing else uses this
// copy but if someone did they might not expect it to change.
m_pMapping = pMapping;
}

// Inputs tab
ControllerInputMappingTableModel* pInputModel =
Expand Down
2 changes: 1 addition & 1 deletion src/controllers/dlgprefcontroller.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class DlgPrefController : public DlgPreferencePage {
QString mappingDescription(const std::shared_ptr<LegacyControllerMapping> pMapping) const;
QString mappingSupportLinks(const std::shared_ptr<LegacyControllerMapping> pMapping) const;
QString mappingFileLinks(const std::shared_ptr<LegacyControllerMapping> pMapping) const;
QString mappingPathFromIndex(int index) const;
QString mappingFilePathFromIndex(int index) const;
QString askForMappingName(const QString& prefilledName = QString()) const;
void applyMappingChanges();
bool saveMapping();
Expand Down
Loading

0 comments on commit 99406cb

Please sign in to comment.