commit 247ff16bae7789dbb271d0d20e66c8a477c94913
parent 20e99c40b7af834e4a4b9b968550fc76b6e04a9d
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date: Sat, 10 Aug 2024 13:21:51 +0200
implement new part select buttons & part active LEDs
Diffstat:
9 files changed, 79 insertions(+), 18 deletions(-)
diff --git a/source/nord/n2x/n2xJucePlugin/n2xEditor.cpp b/source/nord/n2x/n2xJucePlugin/n2xEditor.cpp
@@ -153,7 +153,10 @@ namespace n2xJucePlugin
genericUI::Button<juce::DrawableButton>* Editor::createJuceComponent(genericUI::Button<juce::DrawableButton>* _button, genericUI::UiObject& _object, const std::string& _name, const juce::DrawableButton::ButtonStyle _buttonStyle)
{
- if(_name == "PerfMidiChannelA" || _name == "PerfMidiChannelB" || _name == "PerfMidiChannelC" || _name == "PerfMidiChannelD")
+ if( _name == "PerfSlotActiveA" ||
+ _name == "PerfSlotActiveB" ||
+ _name == "PerfSlotActiveC" ||
+ _name == "PerfSlotActiveD")
return new Part(*this, _name, _buttonStyle);
return jucePluginEditorLib::Editor::createJuceComponent(_button, _object, _name, _buttonStyle);
diff --git a/source/nord/n2x/n2xJucePlugin/n2xParameterDrivenLed.cpp b/source/nord/n2x/n2xJucePlugin/n2xParameterDrivenLed.cpp
@@ -7,10 +7,11 @@
namespace n2xJucePlugin
{
- ParameterDrivenLed::ParameterDrivenLed(Editor& _editor, const std::string& _component, const std::string& _parameter)
+ ParameterDrivenLed::ParameterDrivenLed(Editor& _editor, const std::string& _component, std::string _parameter, uint8_t _part/* = CurrentPart*/)
: m_editor(_editor)
- , m_parameterName(_parameter)
+ , m_parameterName(std::move(_parameter))
, m_led(_editor.findComponentT<juce::Button>(_component))
+ , m_part(_part)
{
auto& c = _editor.getN2xController();
@@ -31,7 +32,7 @@ namespace n2xJucePlugin
{
const auto& c = m_editor.getN2xController();
- m_param = c.getParameter(m_parameterName, c.getCurrentPart());
+ m_param = c.getParameter(m_parameterName, m_part == CurrentPart ? c.getCurrentPart() : m_part);
m_onParamChanged.set(m_param, [this](const pluginLib::Parameter* _parameter)
{
diff --git a/source/nord/n2x/n2xJucePlugin/n2xParameterDrivenLed.h b/source/nord/n2x/n2xJucePlugin/n2xParameterDrivenLed.h
@@ -16,7 +16,9 @@ namespace n2xJucePlugin
class ParameterDrivenLed
{
public:
- explicit ParameterDrivenLed(Editor& _editor, const std::string& _component, const std::string& _parameter);
+ static constexpr uint8_t CurrentPart = 0xff;
+
+ explicit ParameterDrivenLed(Editor& _editor, const std::string& _component, std::string _parameter, uint8_t _part = CurrentPart);
virtual ~ParameterDrivenLed() = default;
protected:
@@ -32,6 +34,7 @@ namespace n2xJucePlugin
Editor& m_editor;
const std::string m_parameterName;
juce::Button* m_led;
+ const uint8_t m_part;
pluginLib::ParameterListener m_onParamChanged;
pluginLib::EventListener<uint8_t> m_onCurrentPartChanged;
diff --git a/source/nord/n2x/n2xJucePlugin/n2xPart.cpp b/source/nord/n2x/n2xJucePlugin/n2xPart.cpp
@@ -30,19 +30,22 @@ namespace n2xJucePlugin
juce::PopupMenu menuChannel;
const auto mp = static_cast<n2x::MultiParam>(n2x::MultiParam::SlotAMidiChannel + getPart());
- const auto ch = controller.getMultiParameter(mp);
+ const auto name = std::string("PerfMidiChannel") + static_cast<char>('A' + getPart());
+ auto* param = controller.getParameter(name, 0);
+ const auto ch = param->getUnnormalizedValue();
+
for(uint8_t c=0; c<16; ++c)
{
- menuChannel.addItem((std::string("Channel ") + std::to_string(c+1)).c_str(), true, c == ch, [&controller, c, mp]
+ menuChannel.addItem((std::string("Channel ") + std::to_string(c+1)).c_str(), true, c == ch, [param, c]
{
- controller.setMultiParameter(mp, c);
+ param->setUnnormalizedValueNotifyingHost(c, pluginLib::Parameter::Origin::Ui);
});
}
menuChannel.addSeparator();
- menuChannel.addItem("Off", true, ch == 16, [&controller, mp]
+ menuChannel.addItem("Off", true, ch >= 16, [param]
{
- controller.setMultiParameter(mp, 16);
+ param->setUnnormalizedValueNotifyingHost(16, pluginLib::Parameter::Origin::Ui);
});
menu.addSubMenu("Midi Channel", menuChannel);
diff --git a/source/nord/n2x/n2xJucePlugin/n2xPartLed.cpp b/source/nord/n2x/n2xJucePlugin/n2xPartLed.cpp
@@ -0,0 +1,26 @@
+#include "n2xPartLed.h"
+
+#include "jucePluginLib/parameter.h"
+
+namespace n2xJucePlugin
+{
+ namespace
+ {
+ std::string getName(const uint8_t _slot)
+ {
+ return std::string("PerfMidiChannel") + static_cast<char>('A' + _slot);
+ }
+ }
+
+ PartLed::PartLed(Editor& _editor, const uint8_t _slot) : ParameterDrivenLed(_editor, getName(_slot), getName(_slot), 0)
+ , m_slot(_slot)
+ {
+ bind();
+ disableClick();
+ }
+
+ bool PartLed::updateToggleState(const pluginLib::Parameter* _parameter) const
+ {
+ return _parameter->getUnnormalizedValue() <= 15;
+ }
+}
diff --git a/source/nord/n2x/n2xJucePlugin/n2xPartLed.h b/source/nord/n2x/n2xJucePlugin/n2xPartLed.h
@@ -0,0 +1,18 @@
+#pragma once
+
+#include "n2xParameterDrivenLed.h"
+
+namespace n2xJucePlugin
+{
+ class PartLed : ParameterDrivenLed
+ {
+ public:
+ PartLed(Editor& _editor, uint8_t _slot);
+
+ protected:
+ bool updateToggleState(const pluginLib::Parameter* _parameter) const override;
+
+ private:
+ const uint8_t m_slot;
+ };
+}
diff --git a/source/nord/n2x/n2xJucePlugin/n2xParts.cpp b/source/nord/n2x/n2xJucePlugin/n2xParts.cpp
@@ -7,10 +7,15 @@ namespace n2xJucePlugin
{
Parts::Parts(Editor& _editor): m_editor(_editor)
{
- m_parts[0] = _editor.findComponentT<Part>("PerfMidiChannelA");
- m_parts[1] = _editor.findComponentT<Part>("PerfMidiChannelB");
- m_parts[2] = _editor.findComponentT<Part>("PerfMidiChannelC");
- m_parts[3] = _editor.findComponentT<Part>("PerfMidiChannelD");
+ m_parts[0] = _editor.findComponentT<Part>("PerfSlotActiveA");
+ m_parts[1] = _editor.findComponentT<Part>("PerfSlotActiveB");
+ m_parts[2] = _editor.findComponentT<Part>("PerfSlotActiveC");
+ m_parts[3] = _editor.findComponentT<Part>("PerfSlotActiveD");
+
+ m_partLeds[0].reset(new PartLed(_editor, 0));
+ m_partLeds[1].reset(new PartLed(_editor, 1));
+ m_partLeds[2].reset(new PartLed(_editor, 2));
+ m_partLeds[3].reset(new PartLed(_editor, 3));
for(uint8_t p=0; p<static_cast<uint8_t>(m_parts.size()); ++p)
{
diff --git a/source/nord/n2x/n2xJucePlugin/n2xParts.h b/source/nord/n2x/n2xJucePlugin/n2xParts.h
@@ -1,6 +1,7 @@
#pragma once
#include "n2xPart.h"
+#include "n2xPartLed.h"
#include "jucePluginLib/event.h"
@@ -19,6 +20,7 @@ namespace n2xJucePlugin
Editor& m_editor;
std::array<Part*,4> m_parts;
+ std::array<std::unique_ptr<PartLed>,4> m_partLeds;
pluginLib::EventListener<uint8_t> onCurrentPartChanged;
};
diff --git a/source/nord/n2x/n2xJucePlugin/parameterDescriptions_n2x.json b/source/nord/n2x/n2xJucePlugin/parameterDescriptions_n2x.json
@@ -88,10 +88,10 @@
{"index":65, "name":"Lfo2Dest", "min":0, "max":8, "isDiscrete":true},
// MULTI aka Performance
- {"class":"NonPartSensitive", "page":10, "index":264, "name":"PerfMidiChannelA", "min":0, "max":15, "isDiscrete":true},
- {"class":"NonPartSensitive", "page":10, "index":265, "name":"PerfMidiChannelB", "min":0, "max":15, "isDiscrete":true},
- {"class":"NonPartSensitive", "page":10, "index":266, "name":"PerfMidiChannelC", "min":0, "max":15, "isDiscrete":true},
- {"class":"NonPartSensitive", "page":10, "index":267, "name":"PerfMidiChannelD", "min":0, "max":15, "isDiscrete":true},
+ {"class":"NonPartSensitive", "page":10, "index":264, "name":"PerfMidiChannelA", "min":0, "max":16, "isDiscrete":true},
+ {"class":"NonPartSensitive", "page":10, "index":265, "name":"PerfMidiChannelB", "min":0, "max":16, "isDiscrete":true},
+ {"class":"NonPartSensitive", "page":10, "index":266, "name":"PerfMidiChannelC", "min":0, "max":16, "isDiscrete":true},
+ {"class":"NonPartSensitive", "page":10, "index":267, "name":"PerfMidiChannelD", "min":0, "max":16, "isDiscrete":true},
{"class":"NonPartSensitive", "page":10, "index":268, "name":"PerfLfo1SyncA", "min":0, "max":7, "isDiscrete":true},
{"class":"NonPartSensitive", "page":10, "index":269, "name":"PerfLfo1SyncB", "min":0, "max":7, "isDiscrete":true},
{"class":"NonPartSensitive", "page":10, "index":270, "name":"PerfLfo1SyncC", "min":0, "max":7, "isDiscrete":true},