commit 8fff62343d7ba927fb7f71dc524242a7c231c478
parent 69257e42ba951b33b7aaf836e3ce378e63e4b2e9
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date: Tue, 6 Aug 2024 22:18:33 +0200
implement VM map
Diffstat:
7 files changed, 176 insertions(+), 22 deletions(-)
diff --git a/source/jucePluginLib/parameterbinding.cpp b/source/jucePluginLib/parameterbinding.cpp
@@ -231,6 +231,27 @@ namespace pluginLib
addBinding(p);
}
+ bool ParameterBinding::bind(juce::Component& _component, const uint32_t _param, const uint8_t _part)
+ {
+ if(auto* slider = dynamic_cast<juce::Slider*>(&_component))
+ {
+ bind(*slider, _param, _part);
+ return true;
+ }
+ if(auto* button = dynamic_cast<juce::DrawableButton*>(&_component))
+ {
+ bind(*button, _param, _part);
+ return true;
+ }
+ if(auto* comboBox = dynamic_cast<juce::ComboBox*>(&_component))
+ {
+ bind(*comboBox, _param, _part);
+ return true;
+ }
+ assert(false && "unknown component type");
+ return false;
+ }
+
juce::Component* ParameterBinding::getBoundComponent(const Parameter* _parameter) const
{
const auto it = m_boundParameters.find(_parameter);
@@ -247,6 +268,37 @@ namespace pluginLib
return it->second;
}
+ bool ParameterBinding::unbind(const Parameter* _param)
+ {
+ for (auto it= m_bindings.begin(); it != m_bindings.end(); ++it)
+ {
+ if(it->parameter != _param)
+ continue;
+
+ m_bindings.erase(it);
+
+ return true;
+ }
+ return false;
+ }
+
+ bool ParameterBinding::unbind(const juce::Component* _component)
+ {
+ for (auto it= m_bindings.begin(); it != m_bindings.end(); ++it)
+ {
+ if(it->component != _component)
+ continue;
+
+ disableBinding(*it);
+
+ m_disabledBindings.push_back(*it);
+ m_bindings.erase(it);
+
+ return true;
+ }
+ return false;
+ }
+
void ParameterBinding::removeMouseListener(juce::Slider& _slider)
{
const auto it = m_sliderMouseListeners.find(&_slider);
@@ -262,27 +314,7 @@ namespace pluginLib
void ParameterBinding::bind(const std::vector<BoundParameter>& _bindings, const bool _currentPartOnly)
{
for (const auto& b : _bindings)
- {
- auto* slider = dynamic_cast<juce::Slider*>(b.component);
- if(slider)
- {
- bind(*slider, b.type, b.part);
- continue;
- }
- auto* button = dynamic_cast<juce::DrawableButton*>(b.component);
- if(button)
- {
- bind(*button, b.type, b.part);
- continue;
- }
- auto* comboBox = dynamic_cast<juce::ComboBox*>(b.component);
- if(comboBox)
- {
- bind(*comboBox, b.type, b.part);
- continue;
- }
- assert(false && "unknown component type");
- }
+ bind(*b.component, b.paramIndex, b.part);
}
void ParameterBinding::addBinding(const BoundParameter& _boundParameter)
diff --git a/source/jucePluginLib/parameterbinding.h b/source/jucePluginLib/parameterbinding.h
@@ -42,7 +42,7 @@ namespace pluginLib
{
Parameter* parameter = nullptr;
juce::Component* component = nullptr;
- uint32_t type = 0xffffffff;
+ uint32_t paramIndex = 0xffffffff;
uint8_t part = CurrentPart;
size_t onChangeListenerId = ParameterListener::InvalidListenerId;
};
@@ -62,6 +62,8 @@ namespace pluginLib
void bind(juce::Button &_control, uint32_t _param);
void bind(juce::Button &_control, uint32_t _param, uint8_t _part);
+ bool bind(juce::Component& _component, uint32_t _param, uint8_t _part);
+
void clearBindings();
void clear();
void setPart(uint8_t _part);
@@ -73,6 +75,9 @@ namespace pluginLib
juce::Component* getBoundComponent(const pluginLib::Parameter* _parameter) const;
pluginLib::Parameter* getBoundParameter(const juce::Component* _component) const;
+ bool unbind(const Parameter* _param);
+ bool unbind(const juce::Component* _component);
+
private:
void removeMouseListener(juce::Slider& _slider);
diff --git a/source/nord/n2x/n2xJucePlugin/CMakeLists.txt b/source/nord/n2x/n2xJucePlugin/CMakeLists.txt
@@ -13,6 +13,7 @@ set(SOURCES
n2xPatchManager.cpp n2xPatchManager.h
n2xPluginEditorState.cpp n2xPluginEditorState.h
n2xPluginProcessor.cpp n2xPluginProcessor.h
+ n2xVmMap.cpp n2xVmMap.h
parameterDescriptions_n2x.json
skins/n2xTrancy/n2xTrancy.json
)
diff --git a/source/nord/n2x/n2xJucePlugin/n2xEditor.cpp b/source/nord/n2x/n2xJucePlugin/n2xEditor.cpp
@@ -10,6 +10,7 @@
#include "n2xParts.h"
#include "n2xPatchManager.h"
#include "n2xPluginProcessor.h"
+#include "n2xVmMap.h"
#include "jucePluginLib/parameterbinding.h"
#include "jucePluginLib/pluginVersion.h"
@@ -72,6 +73,7 @@ namespace n2xJucePlugin
m_lcd.reset(new Lcd(*this));
m_masterVolume.reset(new MasterVolume(*this));
m_parts.reset(new Parts(*this));
+ m_vmMap.reset(new VmMap(*this, m_parameterBinding));
onPartChanged.set(m_controller.onCurrentPartChanged, [this](const uint8_t& _part)
{
@@ -115,6 +117,7 @@ namespace n2xJucePlugin
m_lcd.reset();
m_masterVolume.reset();
m_parts.reset();
+ m_vmMap.reset();
}
const char* Editor::findEmbeddedResource(const std::string& _filename, uint32_t& _size)
diff --git a/source/nord/n2x/n2xJucePlugin/n2xEditor.h b/source/nord/n2x/n2xJucePlugin/n2xEditor.h
@@ -22,6 +22,7 @@ namespace n2xJucePlugin
class Arp;
class Parts;
class MasterVolume;
+ class VmMap;
class Editor final : public jucePluginEditorLib::Editor
{
@@ -60,6 +61,8 @@ namespace n2xJucePlugin
std::unique_ptr<Lcd> m_lcd;
std::unique_ptr<MasterVolume> m_masterVolume;
std::unique_ptr<Parts> m_parts;
+ std::unique_ptr<VmMap> m_vmMap;
+
pluginLib::EventListener<uint8_t> onPartChanged;
std::array<std::string, 4> m_activePatchNames;
diff --git a/source/nord/n2x/n2xJucePlugin/n2xVmMap.cpp b/source/nord/n2x/n2xJucePlugin/n2xVmMap.cpp
@@ -0,0 +1,75 @@
+#include "n2xVmMap.h"
+
+#include "n2xController.h"
+#include "n2xEditor.h"
+
+namespace n2xJucePlugin
+{
+ constexpr const char* g_postfix = "Sens";
+ constexpr float g_enabledAlpha = 0.5f;
+
+ VmMap::VmMap(Editor& _editor, pluginLib::ParameterBinding& _binding)
+ : m_editor(_editor)
+ , m_binding(_binding)
+ , m_btVmMap(_editor.findComponentT<juce::Button>("VMMAP"))
+ {
+ const auto& c = _editor.getN2xController();
+ const auto& descs = c.getParameterDescriptions().getDescriptions();
+
+ for (const auto& desc : descs)
+ {
+ uint32_t idx;
+
+ if(c.getParameterDescriptions().getIndexByName(idx, desc.name + g_postfix))
+ m_paramNames.insert(desc.name);
+ }
+
+ m_btVmMap->onClick = [this]
+ {
+ toggleVmMap(m_btVmMap->getToggleState());
+ };
+ }
+
+ void VmMap::toggleVmMap(const bool _enabled)
+ {
+ if(m_enabled == _enabled)
+ return;
+
+ m_enabled = _enabled;
+
+ const auto& controller = m_editor.getN2xController();
+
+ const auto part = controller.getCurrentPart();
+
+ for (const auto& paramName : m_paramNames)
+ {
+ const auto paramIdxDefault = controller.getParameterIndexByName(paramName);
+ const auto paramIdxVm = controller.getParameterIndexByName(paramName + g_postfix);
+
+ const auto* paramDefault = controller.getParameter(paramName, part);
+ const auto* paramVm = controller.getParameter(paramName + g_postfix, part);
+
+ auto* comp = m_binding.getBoundComponent(paramDefault);
+
+ if(comp == nullptr)
+ comp = m_binding.getBoundComponent(paramVm);
+
+ if(comp != nullptr)
+ {
+ m_binding.unbind(comp);
+ }
+ else
+ {
+ assert(false && "bound component not found");
+ return;
+ }
+
+ m_binding.unbind(paramDefault);
+ m_binding.unbind(paramVm);
+
+ m_binding.bind(*comp, _enabled ? paramIdxVm : paramIdxDefault, pluginLib::ParameterBinding::CurrentPart);
+
+ comp->setAlpha(_enabled ? g_enabledAlpha : 1.0f);
+ }
+ }
+}
diff --git a/source/nord/n2x/n2xJucePlugin/n2xVmMap.h b/source/nord/n2x/n2xJucePlugin/n2xVmMap.h
@@ -0,0 +1,35 @@
+#pragma once
+
+#include <string>
+#include <set>
+
+namespace pluginLib
+{
+ class ParameterBinding;
+}
+
+namespace juce
+{
+ class Button;
+}
+
+namespace n2xJucePlugin
+{
+ class Editor;
+
+ class VmMap
+ {
+ public:
+ explicit VmMap(Editor& _editor, pluginLib::ParameterBinding& _binding);
+
+ private:
+ void toggleVmMap(bool _enabled);
+
+ Editor& m_editor;
+ pluginLib::ParameterBinding& m_binding;
+
+ std::set<std::string> m_paramNames;
+ juce::Button* m_btVmMap;
+ bool m_enabled = false;
+ };
+}