diff --git a/src/controllers/controllermanager.cpp b/src/controllers/controllermanager.cpp index 2fdc8ab11b1..9c1938d8ade 100644 --- a/src/controllers/controllermanager.cpp +++ b/src/controllers/controllermanager.cpp @@ -415,6 +415,7 @@ void ControllerManager::slotApplyMapping(Controller* pController, closeController(pController); // Unset the controller mapping for this controller m_pConfig->remove(key); + emit mappingApplied(false); return; } @@ -432,8 +433,10 @@ void ControllerManager::slotApplyMapping(Controller* pController, if (bEnabled) { openController(pController); + emit mappingApplied(pController->isMappable()); } else { closeController(pController); + emit mappingApplied(false); } } diff --git a/src/controllers/controllermanager.h b/src/controllers/controllermanager.h index 8fb575446aa..4460e0cf816 100644 --- a/src/controllers/controllermanager.h +++ b/src/controllers/controllermanager.h @@ -47,6 +47,7 @@ class ControllerManager : public QObject { void requestSetUpDevices(); void requestShutdown(); void requestInitialize(); + void mappingApplied(bool applied); public slots: void updateControllerList(); diff --git a/src/controllers/dlgprefcontroller.cpp b/src/controllers/dlgprefcontroller.cpp index fd91ecba521..7e83363b426 100644 --- a/src/controllers/dlgprefcontroller.cpp +++ b/src/controllers/dlgprefcontroller.cpp @@ -97,6 +97,11 @@ DlgPrefController::DlgPrefController( &DlgPrefController::applyMapping, m_pControllerManager.get(), &ControllerManager::slotApplyMapping); + // Update GUI + connect(m_pControllerManager.get(), + &ControllerManager::mappingApplied, + this, + &DlgPrefController::enableWizardAndIOTabs); // Open script file links connect(m_ui.labelLoadedMappingScriptFileLinks, @@ -162,6 +167,8 @@ void DlgPrefController::showLearningWizard() { if (!m_pMapping) { m_pMapping = std::shared_ptr(new LegacyMidiControllerMapping()); emit applyMapping(m_pController, m_pMapping, true); + // shortcut for creating and assigning required I/O table models + slotShowMapping(m_pMapping); } // Note that DlgControllerLearning is set to delete itself on close using @@ -471,10 +478,8 @@ void DlgPrefController::slotUpdate() { // If the controller is not mappable, disable the input and output mapping // sections and the learning wizard button. - bool isMappable = m_pController->isMappable(); - m_ui.btnLearningWizard->setEnabled(isMappable); - m_ui.inputMappingsTab->setEnabled(isMappable); - m_ui.outputMappingsTab->setEnabled(isMappable); + enableWizardAndIOTabs(m_pController->isMappable() && m_pController->isOpen()); + // When slotUpdate() is run for the first time, this bool keeps slotPresetSelected() // from setting a false-postive 'dirty' flag when updating the fresh GUI. m_GuiInitialized = true; @@ -537,6 +542,15 @@ QUrl DlgPrefController::helpUrl() const { return QUrl(MIXXX_MANUAL_CONTROLLERS_URL); } +void DlgPrefController::enableWizardAndIOTabs(bool enable) { + // We always enable the Wizard button if this is a MIDI controller so we can + // create a new mapping from scratch with 'No Mapping' + const auto* midiController = qobject_cast(m_pController); + m_ui.btnLearningWizard->setEnabled(midiController != nullptr); + m_ui.inputMappingsTab->setEnabled(enable); + m_ui.outputMappingsTab->setEnabled(enable); +} + QString DlgPrefController::mappingPathFromIndex(int index) const { if (index == 0) { // "No Mapping" item @@ -556,6 +570,7 @@ void DlgPrefController::slotMappingSelected(int chosenIndex) { if (m_GuiInitialized) { setDirty(true); } + enableWizardAndIOTabs(false); } } else { // User picked a mapping m_ui.chkEnabledDevice->setEnabled(true); @@ -569,8 +584,9 @@ void DlgPrefController::slotMappingSelected(int chosenIndex) { } // Check if the mapping is different from the configured mapping - if (m_pControllerManager->getConfiguredMappingFileForDevice( - m_pController->getName()) != mappingPath) { + if (m_GuiInitialized && + m_pControllerManager->getConfiguredMappingFileForDevice( + m_pController->getName()) != mappingPath) { setDirty(true); } diff --git a/src/controllers/dlgprefcontroller.h b/src/controllers/dlgprefcontroller.h index 41de8be0ab8..09569a26828 100644 --- a/src/controllers/dlgprefcontroller.h +++ b/src/controllers/dlgprefcontroller.h @@ -53,6 +53,7 @@ class DlgPrefController : public DlgPreferencePage { void slotShowMapping(std::shared_ptr mapping); /// Called when the Controller Learning Wizard is closed. void slotStopLearning(); + void enableWizardAndIOTabs(bool enable); // Input mappings void addInputMapping(); diff --git a/src/controllers/scripting/legacy/controllerscriptenginelegacy.cpp b/src/controllers/scripting/legacy/controllerscriptenginelegacy.cpp index 14b2fc9569a..78e48d13aa1 100644 --- a/src/controllers/scripting/legacy/controllerscriptenginelegacy.cpp +++ b/src/controllers/scripting/legacy/controllerscriptenginelegacy.cpp @@ -167,11 +167,17 @@ bool ControllerScriptEngineLegacy::initialize() { } void ControllerScriptEngineLegacy::shutdown() { - callFunctionOnObjects(m_scriptFunctionPrefixes, "shutdown"); + // There is no js engine if the mapping was not loaded from a file but by + // creating a new, empty mapping LegacyMidiControllerMapping with the wizard + if (m_pJSEngine) { + callFunctionOnObjects(m_scriptFunctionPrefixes, "shutdown"); + } m_scriptWrappedFunctionCache.clear(); m_incomingDataFunctions.clear(); m_scriptFunctionPrefixes.clear(); - ControllerScriptEngineBase::shutdown(); + if (m_pJSEngine) { + ControllerScriptEngineBase::shutdown(); + } } bool ControllerScriptEngineLegacy::handleIncomingData(const QByteArray& data) {