gearmulator

Emulation of classic VA synths of the late 90s/2000s that are based on Motorola 56300 family DSPs
Log | Files | Refs | Submodules | README | LICENSE

commit d555005fe11e8b1d51e8c489e4761369beecaea1
parent f2ca7b9de15a8dcc6d8cb09bdd1f2136eb4b7711
Author: 790 <790@users.noreply.github.com>
Date:   Tue,  1 Mar 2022 16:11:44 +0000

add skin selector

Diffstat:
Msource/jucePlugin/CMakeLists.txt | 44++++++++++++++++++++++++++++++++++++++++++++
Msource/jucePlugin/PluginEditor.cpp | 54+++++++++++++++++++++++++++++++++++++++++++++++-------
Msource/jucePlugin/PluginEditor.h | 3++-
Msource/jucePlugin/ui2/Ui_Utils.h | 123+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Msource/jucePlugin/ui2/VirusEditor.cpp | 961+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msource/jucePlugin/ui2/VirusEditor.h | 12++++++++----
Msource/jucePlugin/ui2/Virus_Buttons.cpp | 210+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msource/jucePlugin/ui2/Virus_Buttons.h | 151+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msource/jucePlugin/ui2/Virus_LookAndFeel.cpp | 156+++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msource/jucePlugin/ui2/Virus_LookAndFeel.h | 275++++++++++++++++++++++++++++++++++++++-----------------------------------------
Msource/jucePlugin/ui2/Virus_Panel1_OscEditor.cpp | 548+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msource/jucePlugin/ui2/Virus_Panel1_OscEditor.h | 96+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msource/jucePlugin/ui2/Virus_Panel2_LfoEditor.cpp | 518+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Msource/jucePlugin/ui2/Virus_Panel2_LfoEditor.h | 94++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msource/jucePlugin/ui2/Virus_Panel3_FxEditor.cpp | 685++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msource/jucePlugin/ui2/Virus_Panel3_FxEditor.h | 124+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msource/jucePlugin/ui2/Virus_Panel4_ArpEditor.cpp | 755+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msource/jucePlugin/ui2/Virus_Panel4_ArpEditor.h | 106+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msource/jucePlugin/ui2/Virus_Panel5_PatchBrowser.cpp | 1324++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msource/jucePlugin/ui2/Virus_Panel5_PatchBrowser.h | 310+++++++++++++++++++++++++++++++++++++++++--------------------------------------
20 files changed, 3412 insertions(+), 3137 deletions(-)

diff --git a/source/jucePlugin/CMakeLists.txt b/source/jucePlugin/CMakeLists.txt @@ -69,6 +69,24 @@ PRIVATE ui/Virus_PatchBrowser.h ui/Virus_Parts.h ui/Ui_Utils.h + + ui2/Ui_Utils.h + ui2/Virus_Buttons.cpp + ui2/Virus_Buttons.h + ui2/Virus_LookAndFeel.cpp + ui2/Virus_LookAndFeel.h + ui2/Virus_Panel1_OscEditor.cpp + ui2/Virus_Panel1_OscEditor.h + ui2/Virus_Panel2_LfoEditor.cpp + ui2/Virus_Panel2_LfoEditor.h + ui2/Virus_Panel3_FxEditor.cpp + ui2/Virus_Panel3_FxEditor.h + ui2/Virus_Panel4_ArpEditor.cpp + ui2/Virus_Panel4_ArpEditor.h + ui2/Virus_Panel5_PatchBrowser.cpp + ui2/Virus_Panel5_PatchBrowser.h + ui2/VirusEditor.cpp + ui2/VirusEditor.h ) # https://forum.juce.com/t/help-needed-using-binarydata-with-cmake-juce-6/40486 @@ -101,6 +119,32 @@ juce_add_binary_data(jucePlugin_BinaryData "assets/knobs/GenBlue_70x70_100.png" "assets/knobs/GenRed_70x70_100.png" "assets/knobs/multi_18x18_100.png" + "assets2/main_background.png" + "assets2/panels/panel_1.png" + "assets2/panels/panel_2.png" + "assets2/panels/panel_3.png" + "assets2/panels/panel_4.png" + "assets2/panels/panel_5.png" + "assets2/buttons/btn_main_1.png" + "assets2/buttons/btn_main_2.png" + "assets2/buttons/btn_main_3.png" + "assets2/buttons/btn_main_4.png" + "assets2/buttons/btn_main_5.png" + "assets2/buttons/btn_1.png" + "assets2/buttons/btn_2.png" + "assets2/buttons/btn_3.png" + "assets2/buttons/btn_4.png" + "assets2/buttons/btn_left.png" + "assets2/buttons/btn_right.png" + "assets2/buttons/btn_down.png" + "assets2/buttons/btn_menu.png" + "assets2/buttons/btn_load_bank.png" + "assets2/buttons/btn_save_preset.png" + "assets2/combobox/cmb_1.png" + "assets2/combobox/cmb_2.png" + "assets2/knobs/knob_1_128.png" + "assets2/knobs/knob_2_128.png" + "assets2/font/Digital" "parameterDescriptions_C.json" ) diff --git a/source/jucePlugin/PluginEditor.cpp b/source/jucePlugin/PluginEditor.cpp @@ -4,17 +4,18 @@ #include "version.h" #include "ui/VirusEditor.h" - +#include "ui2/VirusEditor.h" //============================================================================== AudioPluginAudioProcessorEditor::AudioPluginAudioProcessorEditor(AudioPluginAudioProcessor &p) : - AudioProcessorEditor(&p), processorRef(p), m_parameterBinding(p), m_virusEditor(new VirusEditor(m_parameterBinding, processorRef)), m_scale("Scale") + AudioProcessorEditor(&p), processorRef(p), m_parameterBinding(p), m_scale("Scale"), m_skin("Skin") { ignoreUnused (processorRef); setSize(1377, 800); const auto config = processorRef.getController().getConfig(); auto scale = config->getIntValue("scale", 100); - m_virusEditor->setTopLeftPosition(0, 0); + int skinId = config->getIntValue("skin", 0); + //m_virusEditor->setTopLeftPosition(0, 0); m_scale.setBounds(0,0,74,24); m_scale.addItem("50%", 50); m_scale.addItem("75%", 75); @@ -22,7 +23,7 @@ AudioPluginAudioProcessorEditor::AudioPluginAudioProcessorEditor(AudioPluginAudi m_scale.addItem("125%", 125); m_scale.addItem("150%", 150); m_scale.addItem("200%", 200); - + m_scale.setSelectedId(scale, juce::dontSendNotification); m_scale.setColour(juce::ComboBox::textColourId, juce::Colours::white); m_scale.onChange = [this, config]() { @@ -32,12 +33,51 @@ AudioPluginAudioProcessorEditor::AudioPluginAudioProcessorEditor(AudioPluginAudi config->saveIfNeeded(); }; setScaleFactor(scale/100.0f); - addAndMakeVisible(m_virusEditor); + + m_skin.setBounds(m_scale.getBounds().getRight() + 4, 0, 74, 24); + m_skin.addItem("Modern", 1); + m_skin.addItem("Classic", 2); + m_skin.setSelectedId(1, juce::dontSendNotification); + m_skin.setColour(juce::ComboBox::textColourId, juce::Colours::white); + m_skin.setSelectedItemIndex(skinId, juce::dontSendNotification); addAndMakeVisible(m_scale); + addAndMakeVisible(m_skin); + m_skin.onChange = [this, config]() { + int skinId = m_skin.getSelectedItemIndex(); + config->setValue("skin", skinId); + config->saveIfNeeded(); + LoadSkin(m_skin.getSelectedItemIndex()); + }; + + LoadSkin(skinId); + //addAndMakeVisible(m_virusEditor); } -AudioPluginAudioProcessorEditor::~AudioPluginAudioProcessorEditor() -{ +void AudioPluginAudioProcessorEditor::LoadSkin(int index) { + if (m_virusEditor != nullptr && getIndexOfChildComponent(m_virusEditor) > -1) + { + removeChildComponent(m_virusEditor); + delete m_virusEditor; + } + + if (index == 1) + { + auto virusEditor = new Trancy::VirusEditor(m_parameterBinding, processorRef); + setSize(virusEditor->iSkinSizeWidth, virusEditor->iSkinSizeHeight); + virusEditor->m_AudioPlugInEditor = (AudioPluginAudioProcessorEditor *)this; + m_virusEditor = (VirusEditor*)virusEditor; + } + else { + m_virusEditor = new VirusEditor(m_parameterBinding, processorRef); + setSize(1377, 800); + } + m_virusEditor->setTopLeftPosition(0, 0); + addAndMakeVisible(m_virusEditor); + m_scale.toFront(0); + m_skin.toFront(0); +} + +AudioPluginAudioProcessorEditor::~AudioPluginAudioProcessorEditor() { delete m_virusEditor; } diff --git a/source/jucePlugin/PluginEditor.h b/source/jucePlugin/PluginEditor.h @@ -18,7 +18,7 @@ public: private: void timerCallback() override; - + void LoadSkin(int index); // This reference is provided as a quick way for your editor to // access the processor object that created it. AudioPluginAudioProcessor& processorRef; @@ -27,6 +27,7 @@ private: // New "real" editor VirusEditor *m_virusEditor; juce::ComboBox m_scale; + juce::ComboBox m_skin; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioPluginAudioProcessorEditor) diff --git a/source/jucePlugin/ui2/Ui_Utils.h b/source/jucePlugin/ui2/Ui_Utils.h @@ -1,67 +1,78 @@ #include "Virus_LookAndFeel.h" #include "../VirusController.h" #include "../../virusLib/microcontrollerTypes.h" - -constexpr auto knobSize = Virus::LookAndFeel::kKnobSize; -constexpr auto knobSizeSmall = Virus::LookAndFeelSmallButton::kKnobSize; - -class Controller; -using namespace virusLib; - -static void setupBackground(juce::Component &parent, std::unique_ptr<juce::Drawable> &bg, const void *data, - const size_t numBytes) +namespace Trancy { - bg = juce::Drawable::createFromImageData(data, numBytes); - parent.addAndMakeVisible(bg.get()); - bg->setBounds(bg->getDrawableBounds().toNearestIntEdges()); -} + using namespace VirusUI; + constexpr auto knobSize = LookAndFeel::kKnobSize; + constexpr auto knobSizeSmall = LookAndFeelSmallButton::kKnobSize; -static void setupRotary(juce::Component &parent, juce::Slider &slider) -{ - slider.setSliderStyle(juce::Slider::RotaryHorizontalVerticalDrag); - slider.setTextBoxStyle(juce::Slider::NoTextBox, false, 0, 0); - parent.addAndMakeVisible(slider); -} + class Controller; + using namespace virusLib; + static void setupBackground(juce::Component &parent, std::unique_ptr<juce::Drawable> &bg, const void *data, + const size_t numBytes) + { + bg = juce::Drawable::createFromImageData(data, numBytes); + parent.addAndMakeVisible(bg.get()); + bg->setBounds(bg->getDrawableBounds().toNearestIntEdges()); + } -static juce::String getCurrentPartBankStr(virusLib::BankNumber currentBank) -{ - switch (currentBank) + static void setupRotary(juce::Component &parent, juce::Slider &slider) { - case virusLib::BankNumber::A: return "A"; - case virusLib::BankNumber::B: return "B"; - case virusLib::BankNumber::C: return "C"; - case virusLib::BankNumber::D: return "D"; - case virusLib::BankNumber::E: return "E"; - case virusLib::BankNumber::F: return "F"; - case virusLib::BankNumber::G: return "G"; - case virusLib::BankNumber::H: return "H"; - case virusLib::BankNumber::EditBuffer: return "EB"; + slider.setSliderStyle(juce::Slider::RotaryHorizontalVerticalDrag); + slider.setTextBoxStyle(juce::Slider::NoTextBox, false, 0, 0); + parent.addAndMakeVisible(slider); } - return "ERR"; -} -static VirusModel guessVersion(uint8_t *data) -{ - if (data[51] > 3) - { - // check extra filter modes - return VirusModel::C; - } - if(data[179] == 0x40 && data[180] == 0x40) // soft knobs don't exist on B so they have fixed value - { - return VirusModel::B; - } - /*if (data[232] != 0x03 || data[235] != 0x6c || data[238] != 0x01) { // extra mod slots - return VirusModel::C; - }*/ - /*if(data[173] != 0x00 || data[174] != 0x00) // EQ - return VirusModel::C;*/ - /*if (data[220] != 0x40 || data[221] != 0x54 || data[222] != 0x20 || data[223] != 0x40 || data[224] != 0x40) { - // eq controls - return VirusModel::C; - }*/ - //return VirusModel::C; + static juce::String getCurrentPartBankStr(virusLib::BankNumber currentBank) + { + switch (currentBank) + { + case virusLib::BankNumber::A: + return "A"; + case virusLib::BankNumber::B: + return "B"; + case virusLib::BankNumber::C: + return "C"; + case virusLib::BankNumber::D: + return "D"; + case virusLib::BankNumber::E: + return "E"; + case virusLib::BankNumber::F: + return "F"; + case virusLib::BankNumber::G: + return "G"; + case virusLib::BankNumber::H: + return "H"; + case virusLib::BankNumber::EditBuffer: + return "EB"; + } + + return "ERR"; + } -} -\ No newline at end of file + static VirusModel guessVersion(uint8_t *data) + { + if (data[51] > 3) + { + // check extra filter modes + return VirusModel::C; + } + if (data[179] == 0x40 && data[180] == 0x40) // soft knobs don't exist on B so they have fixed value + { + return VirusModel::B; + } + /*if (data[232] != 0x03 || data[235] != 0x6c || data[238] != 0x01) { // extra mod slots + return VirusModel::C; + }*/ + /*if(data[173] != 0x00 || data[174] != 0x00) // EQ + return VirusModel::C;*/ + /*if (data[220] != 0x40 || data[221] != 0x54 || data[222] != 0x20 || data[223] != 0x40 || data[224] != 0x40) { + // eq controls + return VirusModel::C; + }*/ + // return VirusModel::C; + } +} // namespace Trancy +\ No newline at end of file diff --git a/source/jucePlugin/ui2/VirusEditor.cpp b/source/jucePlugin/ui2/VirusEditor.cpp @@ -9,483 +9,507 @@ #include "../VirusParameterBinding.h" #include "../VirusController.h" #include "Ui_Utils.h" - -using namespace juce; - -enum Tabs -{ - ArpSettings, - Effects, - LfoMatrix, - OscFilter, - Patches -}; -static uint8_t currentTab = Tabs::OscFilter; - -VirusEditor::VirusEditor(VirusParameterBinding &_parameterBinding, AudioPluginAudioProcessor &_processorRef) : - m_parameterBinding(_parameterBinding), processorRef(_processorRef), m_controller(_processorRef.getController()) ,m_controlLabel("ctrlLabel", ""), m_properties(_processorRef.getController().getConfig()) -{ - setLookAndFeel(&m_lookAndFeel); - - m_background = Drawable::createFromImageData(BinaryData::main_background_png, BinaryData::main_background_pngSize); - m_background->setBufferedToImage (true); - - addAndMakeVisible (*m_background); - addAndMakeVisible (m_mainButtons); - - m_arpEditor = std::make_unique<ArpEditor>(_parameterBinding, processorRef); - m_fxEditor = std::make_unique<FxEditor>(_parameterBinding, processorRef); - m_lfoEditor = std::make_unique<LfoEditor>(_parameterBinding); - m_oscEditor = std::make_unique<OscEditor>(_parameterBinding); - m_patchBrowser = std::make_unique<PatchBrowser>(_parameterBinding, processorRef); - - applyToSections([this](Component *s) { addChildComponent(s); }); - - //Init Keyboard - setWantsKeyboardFocus(true); - addKeyListener(this); - - // show/hide section from buttons.. - m_mainButtons.updateSection = [this]() { - if (m_mainButtons.m_arpSettings.getToggleState()) { - currentTab = Tabs::ArpSettings; - } - else if (m_mainButtons.m_effects.getToggleState()) { - currentTab = Tabs::Effects; - } - else if (m_mainButtons.m_lfoMatrix.getToggleState()) { - currentTab = Tabs::LfoMatrix; - } - else if (m_mainButtons.m_oscFilter.getToggleState()) { - currentTab = Tabs::OscFilter; - } - else if (m_mainButtons.m_patches.getToggleState()) { - currentTab = Tabs::Patches; - } - m_arpEditor->setVisible(m_mainButtons.m_arpSettings.getToggleState()); - m_fxEditor->setVisible(m_mainButtons.m_effects.getToggleState()); - m_lfoEditor->setVisible(m_mainButtons.m_lfoMatrix.getToggleState()); - m_oscEditor->setVisible(m_mainButtons.m_oscFilter.getToggleState()); - m_patchBrowser->setVisible(m_mainButtons.m_patches.getToggleState()); - }; - - uint8_t index = 0; - applyToSections([this, index](Component *s) mutable - { - if (currentTab == index) - { - s->setVisible(true); - } - index++; - }); - - index = 0; - m_mainButtons.applyToMainButtons([this, &index](DrawableButton *s) mutable - { - if (currentTab == index) - { - s->setToggleState(true, dontSendNotification); - } - index++; - }); - - //Draw Main Menu - ShowMainMenue(); - - //MainDisplay (Patchname) - m_patchName.setBounds(1473, 35, 480, 58); - m_patchName.setJustificationType(Justification::left); - m_patchName.setFont(Font("Register", "Normal", 30.f)); - m_patchName.setEditable(false, true, true); - addAndMakeVisible(m_patchName); - - //MainDisplay - m_controlLabel.setBounds(1473, 35, 650, 58); - m_controlLabel.setFont(Font("Register", "Normal", 30.f)); - addAndMakeVisible(m_controlLabel); - - //ToolTip - //m_ToolTip.setLookAndFeel(&m_landfToolTip); - m_ToolTip.setBounds(200, 50, 200, 200); - m_ToolTip.setFont(Font("Register", "Normal", 15.f)); - m_ToolTip.setColour(Label::ColourIds::backgroundColourId, Colours::black); - m_ToolTip.setColour(Label::ColourIds::textColourId, Colours::white); - m_ToolTip.setJustificationType(Justification::centred); - m_ToolTip.setAlpha(0.90); - addAndMakeVisible(m_ToolTip); - m_ToolTip.setVisible(false); - - //MainDisplay Value - m_controlLabelValue.setBounds(1900, 35, 197, 58); - m_controlLabelValue.setJustificationType(Justification::centredRight); - //m_controlLabelValue.setColour(Label::textColourId, Colours::red); - m_controlLabelValue.setFont(Font("Register", "Normal", 30.f)); - addAndMakeVisible(m_controlLabelValue); - - //PresetsSwitch - addAndMakeVisible(m_PresetLeft); - addAndMakeVisible(m_PresetRight); - m_PresetLeft.setBounds(2166 - m_PresetLeft.kWidth / 2, 62 - m_PresetLeft.kHeight / 2, m_PresetLeft.kWidth, m_PresetLeft.kHeight); - m_PresetRight.setBounds(2199 - m_PresetRight.kWidth / 2, 62 - m_PresetRight.kHeight / 2, m_PresetRight.kWidth, m_PresetRight.kHeight); - - m_PresetLeft.onClick = [this]() { - - postCommandMessage(VirusEditor::Commands::PrevPatch); - postCommandMessage(VirusEditor::Commands::UpdateParts); - }; - m_PresetRight.onClick = [this]() - { - postCommandMessage(VirusEditor::Commands::NextPatch); - postCommandMessage(VirusEditor::Commands::UpdateParts); - }; - - //Show Version - m_version.setText(std::string(g_pluginVersionString), NotificationType::dontSendNotification); - m_version.setBounds(250, 1123, 50, 17); - m_version.setColour(Label::textColourId, Colours::silver); - m_version.setFont(Font("Arial", "Bold", 20.f)); - m_version.setJustificationType(Justification::left); - m_version.setJustificationType(Justification::centred); - addAndMakeVisible(m_version); - - //Show Synth Model - m_SynthModel.setText(m_controller.getVirusModel() == virusLib::VirusModel::B ? "B" : "C", NotificationType::dontSendNotification); - m_SynthModel.setBounds(430, 1123, 50, 17); - m_SynthModel.setFont(Font("Arial", "Bold", 20.f)); - m_SynthModel.setJustificationType(Justification::left); - m_SynthModel.setColour(Label::textColourId, Colours::silver); - m_SynthModel.setJustificationType(Justification::centred); - addAndMakeVisible(m_SynthModel); - - //Show RomName - m_RomName.setText(_processorRef.getRomName()+".bin", NotificationType::dontSendNotification); - m_RomName.setBounds(642, 1123, 150, 17); - m_RomName.setColour(Label::textColourId, Colours::silver); - m_RomName.setFont(Font("Arial", "Bold", 20.f)); - m_RomName.setJustificationType(Justification::left); - m_RomName.setJustificationType(Justification::centred); - addAndMakeVisible(m_RomName); - - //Hyperlink - m_hyperLink.setBounds(900, 1115, 400, 35); - m_hyperLink.setColour(Label::textColourId, Colours::silver); - m_hyperLink.setFont(Font("Arial", "Bold", 20.f), true, dontSendNotification); - m_hyperLink.setJustificationType(Justification::left); - m_hyperLink.setJustificationType(Justification::centred); - addAndMakeVisible(m_hyperLink); - - - m_controller.onProgramChange = [this]() - { - updateParts(); - m_arpEditor->refreshParts(); - }; - m_controller.onMsgDone = [this]() - { - m_controller.onMsgDone = nullptr; - postCommandMessage(VirusEditor::Commands::InitPatches); - postCommandMessage(VirusEditor::Commands::SelectFirstPatch); - postCommandMessage(VirusEditor::Commands::UpdateParts); - }; - - m_controller.getBankCount(); - addMouseListener(this, true); - setSize (kPanelWidth, kPanelHeight); -} - -VirusEditor::~VirusEditor() -{ - m_controller.onProgramChange = nullptr; - m_mainMenu.onClick = nullptr; - selectorMenu.setLookAndFeel(nullptr); - SubSkinSizeSelector.setLookAndFeel(nullptr); - m_mainMenu.setLookAndFeel (nullptr); - selector.setLookAndFeel (nullptr); - setLookAndFeel(nullptr); -} - -bool VirusEditor::keyPressed(const KeyPress &k, Component *c) -{ - if( k.getKeyCode() == 65573) - { - postCommandMessage(VirusEditor::Commands::PrevPatch); - } - if( k.getKeyCode() == 65575) - { - postCommandMessage(VirusEditor::Commands::NextPatch); - } - //43 + - //45 - - return true; -} - -void VirusEditor::updateParts() -{ - const auto multiMode = m_controller.isMultiMode(); - for (auto pt = 0; pt < 16; pt++) - { - bool singlePartOrInMulti = pt == 0 || multiMode; - if (pt == m_controller.getCurrentPart()) - { - if (m_patchBrowser->GetIsFileMode()) - { - m_patchName.setText("["+String(m_controller.getCurrentPart()+1) - +"][FILE] " - + String(m_patchBrowser->GetTablePatchList()->getSelectedRow(0)+1)+": " + m_patchBrowser->GetLastPatchSelected(), dontSendNotification); - } - else - { - const auto patchName = m_controller.getCurrentPartPresetName(pt); - if(m_patchName.getText() != patchName) - { - String sZero; - m_patchName.setText("["+String(m_controller.getCurrentPart()+1) - +"][" + m_patchBrowser->GetSelectBankNum() + "] " - + String(processorRef.getController().getCurrentPartProgram(m_controller.getCurrentPart())+1)+": " + patchName, dontSendNotification); - } - } - } - } -} - - -void VirusEditor::ShowMainMenue() +class VirusParameterBinding; +namespace Trancy { - m_mainMenu.setLookAndFeel (&m_landfButtons); - - m_mainMenu.onClick = [this]() - { - selectorMenu.setLookAndFeel(&m_landfButtons); - selectorMenu.clear(); - SubSkinSizeSelector.setLookAndFeel(&m_landfButtons); - SubSkinSizeSelector.clear(); - - for (float d = 375; d < 1250; d = d + 125) - { - SubSkinSizeSelector.addItem(std::to_string(200 * int(d) / 1000) + "%", [this, d] - { - double dScaleFactor = float(d / 1000.0); - m_AudioPlugInEditor->setScaleFactor(dScaleFactor); - (*this).setSize(iSkinSizeWidth, iSkinSizeHeight); - m_properties->setValue("skin_scale_factor", String(dScaleFactor)); - m_properties->save(); - }); - } - - selectorMenu.addSubMenu("Skin size", SubSkinSizeSelector, true); - selectorMenu.addItem("About", [this]() { AboutWindow(); }); - selectorMenu.showMenu(PopupMenu::Options()); + using namespace juce; + + enum Tabs + { + ArpSettings, + Effects, + LfoMatrix, + OscFilter, + Patches }; + static uint8_t currentTab = Tabs::OscFilter; - //draw Main Menu Button - m_mainMenu.setBounds(2301 - m_mainMenu.kWidth / 2, 62 - m_mainMenu.kHeight / 2, m_mainMenu.kWidth, m_mainMenu.kHeight); - addAndMakeVisible(m_mainMenu); -} - - -void VirusEditor::applyToSections(std::function<void(Component *)> action) -{ - for (auto *section : {static_cast<Component *>(m_arpEditor.get()), static_cast<Component *>(m_fxEditor.get()), - static_cast<Component *>(m_lfoEditor.get()), static_cast<Component *>(m_oscEditor.get()), - static_cast<Component *>(m_patchBrowser.get())}) - { - action(section); - } -} - -void VirusEditor::MainButtons::applyToMainButtons(std::function<void(DrawableButton *)> action) -{ - for (auto *section : {static_cast<DrawableButton *>(&m_arpSettings), static_cast<DrawableButton *>(&m_effects), - static_cast<DrawableButton *>(&m_lfoMatrix), static_cast<DrawableButton *>(&m_oscFilter), - static_cast<DrawableButton *>(&m_patches)}) - { - action(section); - } -} - - -void VirusEditor::updateControlLabel(Component* eventComponent) -{ - auto props = eventComponent->getProperties(); - if(props.contains("type") && props["type"] == "slider") { - - auto comp = dynamic_cast<Slider*>(eventComponent); - if(comp && comp->isEnabled()) - { - int iValue = (props.contains("bipolar") && props["bipolar"])?roundToInt(comp->getValue())-64:roundToInt(comp->getValue()); - - //ToolTip handle - m_ToolTip.setVisible(true); - m_ToolTip.setText(std::to_string(iValue), dontSendNotification); - //todo --> ugly --> Need to be fixed - m_ToolTip.setBounds(comp->getX()+comp->getWidth()*2-43, comp->getY()+comp->getHeight()*2+83, 70,30); - m_ToolTip.toFront(true); - - //Main display handle - m_controlLabel.setVisible(true); - m_controlLabelValue.setVisible(true); - m_patchName.setVisible(false); - - if(m_paramDisplayLocal) - { - m_controlLabel.setColour(Label::ColourIds::backgroundColourId, Colours::black); - m_controlLabel.setColour(Label::ColourIds::outlineColourId, Colours::white); - } - - m_controlLabel.setText(props["name"].toString(), dontSendNotification); - m_controlLabelValue.setText(String(iValue), dontSendNotification); - } - } - -} -void VirusEditor::mouseDrag(const MouseEvent & event) -{ - updateControlLabel(event.eventComponent); -} - -void VirusEditor::mouseEnter(const MouseEvent& event) -{ - if (event.mouseWasDraggedSinceMouseDown()) { - return; - } - updateControlLabel(event.eventComponent); -} - -void VirusEditor::mouseExit(const MouseEvent& event) -{ - if (event.mouseWasDraggedSinceMouseDown()) { - return; - } - m_controlLabel.setText("", dontSendNotification); - m_controlLabel.setVisible(false); - m_controlLabelValue.setVisible(false); - m_patchName.setVisible(true); - m_ToolTip.setVisible(false); -} - -void VirusEditor::mouseDown(const MouseEvent &event) -{ -} - -void VirusEditor::mouseUp(const MouseEvent & event) -{ - m_controlLabel.setText("", dontSendNotification); - m_controlLabel.setVisible(false); - m_controlLabelValue.setVisible(false); - m_patchName.setVisible(true); - m_ToolTip.setVisible(false); -} -void VirusEditor::mouseWheelMove(const MouseEvent& event, const MouseWheelDetails& wheel) -{ - updateControlLabel(event.eventComponent); -} - - -void VirusEditor::resized() -{ - m_background->setBounds (getLocalBounds()); - - //Position of first main button (osc/filt) - m_mainButtons.setBounds(121, 36, m_mainButtons.getWidth(), m_mainButtons.getHeight()); - - // Panel Positions - applyToSections([this](Component *s) { s->setTopLeftPosition(101, 120); }); -} + VirusEditor::VirusEditor(VirusParameterBinding &_parameterBinding, AudioPluginAudioProcessor &_processorRef) : + m_parameterBinding(_parameterBinding), processorRef(_processorRef), m_controller(_processorRef.getController()), + m_controlLabel("ctrlLabel", ""), m_properties(_processorRef.getController().getConfig()) + { + setLookAndFeel(&m_lookAndFeel); -void VirusEditor::handleCommandMessage(int commandId) -{ - switch (commandId) { - case Commands::Rebind: recreateControls(); - case Commands::UpdateParts: - { - updateParts(); - m_arpEditor->refreshParts(); - }; break; - case Commands::InitPatches: - { - m_patchBrowser->IntiPatches(); - }; break; - case Commands::PrevPatch: - { - if (m_patchBrowser->GetTablePatchList()->getSelectedRow(0)>0) - { - m_patchBrowser->GetTablePatchList()->selectRow(m_patchBrowser->GetTablePatchList()->getSelectedRow(0)-1,false,false); - } - };break; - case Commands::NextPatch: - { - if (m_patchBrowser->GetTablePatchList()->getSelectedRow(0)<m_patchBrowser->GetTablePatchList()->getNumRows()-1) - { - m_patchBrowser->GetTablePatchList()->selectRow(m_patchBrowser->GetTablePatchList()->getSelectedRow(0)+1,false,false); - } - };break; - case Commands::SelectFirstPatch: - { - m_patchBrowser->GetTablePatchList()->selectRow(0,false,false); - };break; - - default: return; - } -} - -void VirusEditor::recreateControls() -{ - removeChildComponent(m_oscEditor.get()); - removeChildComponent(m_lfoEditor.get()); - removeChildComponent(m_fxEditor.get()); - removeChildComponent(m_arpEditor.get()); - // removeChildComponent(m_patchBrowser.get()); - - m_oscEditor = std::make_unique<OscEditor>(m_parameterBinding); - addChildComponent(m_oscEditor.get()); + m_background = + Drawable::createFromImageData(BinaryData::main_background_png, BinaryData::main_background_pngSize); + m_background->setBufferedToImage(true); - m_lfoEditor = std::make_unique<LfoEditor>(m_parameterBinding); - addChildComponent(m_lfoEditor.get()); + addAndMakeVisible(*m_background); + addAndMakeVisible(m_mainButtons); - m_fxEditor = std::make_unique<FxEditor>(m_parameterBinding, processorRef); - addChildComponent(m_fxEditor.get()); + m_arpEditor = std::make_unique<ArpEditor>(_parameterBinding, processorRef); + m_fxEditor = std::make_unique<FxEditor>(_parameterBinding, processorRef); + m_lfoEditor = std::make_unique<LfoEditor>(_parameterBinding); + m_oscEditor = std::make_unique<OscEditor>(_parameterBinding); + m_patchBrowser = std::make_unique<PatchBrowser>(_parameterBinding, processorRef); - m_arpEditor = std::make_unique<ArpEditor>(m_parameterBinding, processorRef); - addChildComponent(m_arpEditor.get()); + applyToSections([this](Component *s) { addChildComponent(s); }); - //m_patchBrowser = std::make_unique<PatchBrowser>(m_parameterBinding, processorRef); - //addChildComponent(m_patchBrowser.get()); + // Init Keyboard + setWantsKeyboardFocus(true); + addKeyListener(this); - m_mainButtons.updateSection(); - resized(); -} - -VirusEditor::MainButtons::MainButtons() -: m_oscFilter ("OSC|FILTER", DrawableButton::ImageRaw) -, m_lfoMatrix ("LFO|MATRIX", DrawableButton::ImageRaw) -, m_effects ("EFFECTS", DrawableButton::ImageRaw) -, m_arpSettings ("ARP|SETTINGS", DrawableButton::ImageRaw) -, m_patches("PATCHES", DrawableButton::ImageRaw) -{ - constexpr auto numOfMainButtons = 5; - setupButton(0, Drawable::createFromImageData(BinaryData::btn_main_1_png, BinaryData::btn_main_1_pngSize), m_oscFilter); - setupButton(1, Drawable::createFromImageData(BinaryData::btn_main_2_png, BinaryData::btn_main_2_pngSize), m_lfoMatrix); - setupButton(2, Drawable::createFromImageData(BinaryData::btn_main_3_png, BinaryData::btn_main_3_pngSize), m_effects); - setupButton(3, Drawable::createFromImageData(BinaryData::btn_main_4_png, BinaryData::btn_main_4_pngSize), m_arpSettings); - setupButton(4, Drawable::createFromImageData(BinaryData::btn_main_5_png, BinaryData::btn_main_5_pngSize), m_patches); - setSize ((kButtonWidth + kMargin) * numOfMainButtons, kButtonHeight); -} - - -void VirusEditor::MainButtons::valueChanged(Value &) { updateSection(); } - -void VirusEditor::MainButtons::setupButton (int i, std::unique_ptr<Drawable>&& btnImage, DrawableButton& btn) -{ - auto onImage = btnImage->createCopy(); - onImage->setOriginWithOriginalSize({0, -kButtonHeight}); - btn.setClickingTogglesState (true); - btn.setRadioGroupId (kGroupId); - btn.setImages (btnImage.get(), nullptr, nullptr, nullptr, onImage.get()); - btn.setBounds ((i > 1 ? -1 : 0) + i * (kButtonWidth + kMargin)-5, 0, kButtonWidth, kButtonHeight); - btn.getToggleStateValue().addListener(this); - addAndMakeVisible (btn); -} + // show/hide section from buttons.. + m_mainButtons.updateSection = [this]() { + if (m_mainButtons.m_arpSettings.getToggleState()) + { + currentTab = Tabs::ArpSettings; + } + else if (m_mainButtons.m_effects.getToggleState()) + { + currentTab = Tabs::Effects; + } + else if (m_mainButtons.m_lfoMatrix.getToggleState()) + { + currentTab = Tabs::LfoMatrix; + } + else if (m_mainButtons.m_oscFilter.getToggleState()) + { + currentTab = Tabs::OscFilter; + } + else if (m_mainButtons.m_patches.getToggleState()) + { + currentTab = Tabs::Patches; + } + m_arpEditor->setVisible(m_mainButtons.m_arpSettings.getToggleState()); + m_fxEditor->setVisible(m_mainButtons.m_effects.getToggleState()); + m_lfoEditor->setVisible(m_mainButtons.m_lfoMatrix.getToggleState()); + m_oscEditor->setVisible(m_mainButtons.m_oscFilter.getToggleState()); + m_patchBrowser->setVisible(m_mainButtons.m_patches.getToggleState()); + }; + + uint8_t index = 0; + applyToSections([this, index](Component *s) mutable { + if (currentTab == index) + { + s->setVisible(true); + } + index++; + }); + + index = 0; + m_mainButtons.applyToMainButtons([this, &index](DrawableButton *s) mutable { + if (currentTab == index) + { + s->setToggleState(true, dontSendNotification); + } + index++; + }); + + // Draw Main Menu + ShowMainMenue(); + + // MainDisplay (Patchname) + m_patchName.setBounds(1473, 35, 480, 58); + m_patchName.setJustificationType(Justification::left); + m_patchName.setFont(Font("Register", "Normal", 30.f)); + m_patchName.setEditable(false, true, true); + addAndMakeVisible(m_patchName); + + // MainDisplay + m_controlLabel.setBounds(1473, 35, 650, 58); + m_controlLabel.setFont(Font("Register", "Normal", 30.f)); + addAndMakeVisible(m_controlLabel); + + // ToolTip + // m_ToolTip.setLookAndFeel(&m_landfToolTip); + m_ToolTip.setBounds(200, 50, 200, 200); + m_ToolTip.setFont(Font("Register", "Normal", 15.f)); + m_ToolTip.setColour(Label::ColourIds::backgroundColourId, Colours::black); + m_ToolTip.setColour(Label::ColourIds::textColourId, Colours::white); + m_ToolTip.setJustificationType(Justification::centred); + m_ToolTip.setAlpha(0.90); + addAndMakeVisible(m_ToolTip); + m_ToolTip.setVisible(false); + + // MainDisplay Value + m_controlLabelValue.setBounds(1900, 35, 197, 58); + m_controlLabelValue.setJustificationType(Justification::centredRight); + // m_controlLabelValue.setColour(Label::textColourId, Colours::red); + m_controlLabelValue.setFont(Font("Register", "Normal", 30.f)); + addAndMakeVisible(m_controlLabelValue); + + // PresetsSwitch + addAndMakeVisible(m_PresetLeft); + addAndMakeVisible(m_PresetRight); + m_PresetLeft.setBounds(2166 - m_PresetLeft.kWidth / 2, 62 - m_PresetLeft.kHeight / 2, m_PresetLeft.kWidth, + m_PresetLeft.kHeight); + m_PresetRight.setBounds(2199 - m_PresetRight.kWidth / 2, 62 - m_PresetRight.kHeight / 2, m_PresetRight.kWidth, + m_PresetRight.kHeight); + + m_PresetLeft.onClick = [this]() { + postCommandMessage(VirusEditor::Commands::PrevPatch); + postCommandMessage(VirusEditor::Commands::UpdateParts); + }; + m_PresetRight.onClick = [this]() { + postCommandMessage(VirusEditor::Commands::NextPatch); + postCommandMessage(VirusEditor::Commands::UpdateParts); + }; + + // Show Version + m_version.setText(std::string(g_pluginVersionString), NotificationType::dontSendNotification); + m_version.setBounds(250, 1123, 50, 17); + m_version.setColour(Label::textColourId, Colours::silver); + m_version.setFont(Font("Arial", "Bold", 20.f)); + m_version.setJustificationType(Justification::left); + m_version.setJustificationType(Justification::centred); + addAndMakeVisible(m_version); + + // Show Synth Model + m_SynthModel.setText(m_controller.getVirusModel() == virusLib::VirusModel::B ? "B" : "C", + NotificationType::dontSendNotification); + m_SynthModel.setBounds(430, 1123, 50, 17); + m_SynthModel.setFont(Font("Arial", "Bold", 20.f)); + m_SynthModel.setJustificationType(Justification::left); + m_SynthModel.setColour(Label::textColourId, Colours::silver); + m_SynthModel.setJustificationType(Justification::centred); + addAndMakeVisible(m_SynthModel); + + // Show RomName + m_RomName.setText(_processorRef.getRomName() + ".bin", NotificationType::dontSendNotification); + m_RomName.setBounds(642, 1123, 150, 17); + m_RomName.setColour(Label::textColourId, Colours::silver); + m_RomName.setFont(Font("Arial", "Bold", 20.f)); + m_RomName.setJustificationType(Justification::left); + m_RomName.setJustificationType(Justification::centred); + addAndMakeVisible(m_RomName); + + // Hyperlink + m_hyperLink.setBounds(900, 1115, 400, 35); + m_hyperLink.setColour(Label::textColourId, Colours::silver); + m_hyperLink.setFont(Font("Arial", "Bold", 20.f), true, dontSendNotification); + m_hyperLink.setJustificationType(Justification::left); + m_hyperLink.setJustificationType(Justification::centred); + addAndMakeVisible(m_hyperLink); + + + m_controller.onProgramChange = [this]() { + updateParts(); + m_arpEditor->refreshParts(); + }; + m_controller.onMsgDone = [this]() { + m_controller.onMsgDone = nullptr; + postCommandMessage(VirusEditor::Commands::InitPatches); + postCommandMessage(VirusEditor::Commands::SelectFirstPatch); + postCommandMessage(VirusEditor::Commands::UpdateParts); + }; + + m_controller.getBankCount(); + addMouseListener(this, true); + setSize(kPanelWidth, kPanelHeight); + } + + VirusEditor::~VirusEditor() + { + m_controller.onProgramChange = nullptr; + m_mainMenu.onClick = nullptr; + selectorMenu.setLookAndFeel(nullptr); + SubSkinSizeSelector.setLookAndFeel(nullptr); + m_mainMenu.setLookAndFeel(nullptr); + selector.setLookAndFeel(nullptr); + setLookAndFeel(nullptr); + } + + bool VirusEditor::keyPressed(const KeyPress &k, Component *c) + { + if (k.getKeyCode() == 65573) + { + postCommandMessage(VirusEditor::Commands::PrevPatch); + } + if (k.getKeyCode() == 65575) + { + postCommandMessage(VirusEditor::Commands::NextPatch); + } + // 43 + + // 45 - + return true; + } + + void VirusEditor::updateParts() + { + const auto multiMode = m_controller.isMultiMode(); + for (auto pt = 0; pt < 16; pt++) + { + bool singlePartOrInMulti = pt == 0 || multiMode; + if (pt == m_controller.getCurrentPart()) + { + if (m_patchBrowser->GetIsFileMode()) + { + m_patchName.setText("[" + String(m_controller.getCurrentPart() + 1) + "][FILE] " + + String(m_patchBrowser->GetTablePatchList()->getSelectedRow(0) + 1) + ": " + + m_patchBrowser->GetLastPatchSelected(), + dontSendNotification); + } + else + { + const auto patchName = m_controller.getCurrentPartPresetName(pt); + if (m_patchName.getText() != patchName) + { + String sZero; + m_patchName.setText("[" + String(m_controller.getCurrentPart() + 1) + "][" + + m_patchBrowser->GetSelectBankNum() + "] " + + String(processorRef.getController().getCurrentPartProgram( + m_controller.getCurrentPart()) + + 1) + + ": " + patchName, + dontSendNotification); + } + } + } + } + } + + + void VirusEditor::ShowMainMenue() + { + m_mainMenu.setLookAndFeel(&m_landfButtons); + + m_mainMenu.onClick = [this]() { + selectorMenu.setLookAndFeel(&m_landfButtons); + selectorMenu.clear(); + SubSkinSizeSelector.setLookAndFeel(&m_landfButtons); + SubSkinSizeSelector.clear(); + + for (float d = 375; d < 1250; d = d + 125) + { + SubSkinSizeSelector.addItem(std::to_string(200 * int(d) / 1000) + "%", [this, d] { + double dScaleFactor = float(d / 1000.0); + m_AudioPlugInEditor->setScaleFactor(dScaleFactor); + (*this).setSize(iSkinSizeWidth, iSkinSizeHeight); + m_properties->setValue("skin_scale_factor", String(dScaleFactor)); + m_properties->save(); + }); + } + + selectorMenu.addSubMenu("Skin size", SubSkinSizeSelector, true); + selectorMenu.addItem("About", [this]() { AboutWindow(); }); + selectorMenu.showMenu(PopupMenu::Options()); + }; + + // draw Main Menu Button + m_mainMenu.setBounds(2301 - m_mainMenu.kWidth / 2, 62 - m_mainMenu.kHeight / 2, m_mainMenu.kWidth, + m_mainMenu.kHeight); + addAndMakeVisible(m_mainMenu); + } + + + void VirusEditor::applyToSections(std::function<void(Component *)> action) + { + for (auto *section : {static_cast<Component *>(m_arpEditor.get()), static_cast<Component *>(m_fxEditor.get()), + static_cast<Component *>(m_lfoEditor.get()), static_cast<Component *>(m_oscEditor.get()), + static_cast<Component *>(m_patchBrowser.get())}) + { + action(section); + } + } + + void VirusEditor::MainButtons::applyToMainButtons(std::function<void(DrawableButton *)> action) + { + for (auto *section : {static_cast<DrawableButton *>(&m_arpSettings), static_cast<DrawableButton *>(&m_effects), + static_cast<DrawableButton *>(&m_lfoMatrix), static_cast<DrawableButton *>(&m_oscFilter), + static_cast<DrawableButton *>(&m_patches)}) + { + action(section); + } + } -void VirusEditor::AboutWindow() {} + void VirusEditor::updateControlLabel(Component *eventComponent) + { + auto props = eventComponent->getProperties(); + if (props.contains("type") && props["type"] == "slider") + { + auto comp = dynamic_cast<Slider *>(eventComponent); + if (comp && comp->isEnabled()) + { + int iValue = (props.contains("bipolar") && props["bipolar"]) ? roundToInt(comp->getValue()) - 64 + : roundToInt(comp->getValue()); + + // ToolTip handle + m_ToolTip.setVisible(true); + m_ToolTip.setText(std::to_string(iValue), dontSendNotification); + // todo --> ugly --> Need to be fixed + m_ToolTip.setBounds(comp->getX() + comp->getWidth() * 2 - 43, comp->getY() + comp->getHeight() * 2 + 83, + 70, 30); + m_ToolTip.toFront(true); + + // Main display handle + m_controlLabel.setVisible(true); + m_controlLabelValue.setVisible(true); + m_patchName.setVisible(false); + + if (m_paramDisplayLocal) + { + m_controlLabel.setColour(Label::ColourIds::backgroundColourId, Colours::black); + m_controlLabel.setColour(Label::ColourIds::outlineColourId, Colours::white); + } + + m_controlLabel.setText(props["name"].toString(), dontSendNotification); + m_controlLabelValue.setText(String(iValue), dontSendNotification); + } + } + } + void VirusEditor::mouseDrag(const MouseEvent &event) { updateControlLabel(event.eventComponent); } + + void VirusEditor::mouseEnter(const MouseEvent &event) + { + if (event.mouseWasDraggedSinceMouseDown()) + { + return; + } + updateControlLabel(event.eventComponent); + } + + void VirusEditor::mouseExit(const MouseEvent &event) + { + if (event.mouseWasDraggedSinceMouseDown()) + { + return; + } + m_controlLabel.setText("", dontSendNotification); + m_controlLabel.setVisible(false); + m_controlLabelValue.setVisible(false); + m_patchName.setVisible(true); + m_ToolTip.setVisible(false); + } + + void VirusEditor::mouseDown(const MouseEvent &event) {} + + void VirusEditor::mouseUp(const MouseEvent &event) + { + m_controlLabel.setText("", dontSendNotification); + m_controlLabel.setVisible(false); + m_controlLabelValue.setVisible(false); + m_patchName.setVisible(true); + m_ToolTip.setVisible(false); + } + void VirusEditor::mouseWheelMove(const MouseEvent &event, const MouseWheelDetails &wheel) + { + updateControlLabel(event.eventComponent); + } + + + void VirusEditor::resized() + { + m_background->setBounds(getLocalBounds()); + + // Position of first main button (osc/filt) + m_mainButtons.setBounds(121, 36, m_mainButtons.getWidth(), m_mainButtons.getHeight()); + + // Panel Positions + applyToSections([this](Component *s) { s->setTopLeftPosition(101, 120); }); + } + + void VirusEditor::handleCommandMessage(int commandId) + { + switch (commandId) + { + case Commands::Rebind: + recreateControls(); + case Commands::UpdateParts: + { + updateParts(); + m_arpEditor->refreshParts(); + }; + break; + case Commands::InitPatches: + { + m_patchBrowser->IntiPatches(); + }; + break; + case Commands::PrevPatch: + { + if (m_patchBrowser->GetTablePatchList()->getSelectedRow(0) > 0) + { + m_patchBrowser->GetTablePatchList()->selectRow( + m_patchBrowser->GetTablePatchList()->getSelectedRow(0) - 1, false, false); + } + }; + break; + case Commands::NextPatch: + { + if (m_patchBrowser->GetTablePatchList()->getSelectedRow(0) < + m_patchBrowser->GetTablePatchList()->getNumRows() - 1) + { + m_patchBrowser->GetTablePatchList()->selectRow( + m_patchBrowser->GetTablePatchList()->getSelectedRow(0) + 1, false, false); + } + }; + break; + case Commands::SelectFirstPatch: + { + m_patchBrowser->GetTablePatchList()->selectRow(0, false, false); + }; + break; + + default: + return; + } + } + + void VirusEditor::recreateControls() + { + removeChildComponent(m_oscEditor.get()); + removeChildComponent(m_lfoEditor.get()); + removeChildComponent(m_fxEditor.get()); + removeChildComponent(m_arpEditor.get()); + // removeChildComponent(m_patchBrowser.get()); + + m_oscEditor = std::make_unique<OscEditor>(m_parameterBinding); + addChildComponent(m_oscEditor.get()); + + m_lfoEditor = std::make_unique<LfoEditor>(m_parameterBinding); + addChildComponent(m_lfoEditor.get()); + + m_fxEditor = std::make_unique<FxEditor>(m_parameterBinding, processorRef); + addChildComponent(m_fxEditor.get()); + + m_arpEditor = std::make_unique<ArpEditor>(m_parameterBinding, processorRef); + addChildComponent(m_arpEditor.get()); + + // m_patchBrowser = std::make_unique<PatchBrowser>(m_parameterBinding, processorRef); + // addChildComponent(m_patchBrowser.get()); + + m_mainButtons.updateSection(); + resized(); + } + + VirusEditor::MainButtons::MainButtons() : + m_oscFilter("OSC|FILTER", DrawableButton::ImageRaw), m_lfoMatrix("LFO|MATRIX", DrawableButton::ImageRaw), + m_effects("EFFECTS", DrawableButton::ImageRaw), m_arpSettings("ARP|SETTINGS", DrawableButton::ImageRaw), + m_patches("PATCHES", DrawableButton::ImageRaw) + { + constexpr auto numOfMainButtons = 5; + setupButton(0, Drawable::createFromImageData(BinaryData::btn_main_1_png, BinaryData::btn_main_1_pngSize), + m_oscFilter); + setupButton(1, Drawable::createFromImageData(BinaryData::btn_main_2_png, BinaryData::btn_main_2_pngSize), + m_lfoMatrix); + setupButton(2, Drawable::createFromImageData(BinaryData::btn_main_3_png, BinaryData::btn_main_3_pngSize), + m_effects); + setupButton(3, Drawable::createFromImageData(BinaryData::btn_main_4_png, BinaryData::btn_main_4_pngSize), + m_arpSettings); + setupButton(4, Drawable::createFromImageData(BinaryData::btn_main_5_png, BinaryData::btn_main_5_pngSize), + m_patches); + setSize((kButtonWidth + kMargin) * numOfMainButtons, kButtonHeight); + } + + + void VirusEditor::MainButtons::valueChanged(Value &) { updateSection(); } + + void VirusEditor::MainButtons::setupButton(int i, std::unique_ptr<Drawable> &&btnImage, DrawableButton &btn) + { + auto onImage = btnImage->createCopy(); + onImage->setOriginWithOriginalSize({0, -kButtonHeight}); + btn.setClickingTogglesState(true); + btn.setRadioGroupId(kGroupId); + btn.setImages(btnImage.get(), nullptr, nullptr, nullptr, onImage.get()); + btn.setBounds((i > 1 ? -1 : 0) + i * (kButtonWidth + kMargin) - 5, 0, kButtonWidth, kButtonHeight); + btn.getToggleStateValue().addListener(this); + addAndMakeVisible(btn); + } + + + void VirusEditor::AboutWindow() {} + +} // namespace Trancy +\ No newline at end of file diff --git a/source/jucePlugin/ui2/VirusEditor.h b/source/jucePlugin/ui2/VirusEditor.h @@ -6,8 +6,10 @@ #include "Virus_LookAndFeel.h" #include "../VirusController.h" #include "Virus_LookAndFeel.h" - class VirusParameterBinding; +namespace Trancy +{ + class OscEditor; class LfoEditor; class FxEditor; @@ -100,9 +102,9 @@ private: std::unique_ptr<PatchBrowser> m_patchBrowser; std::unique_ptr<juce::Drawable> m_background; - Virus::LookAndFeel m_lookAndFeel; - Virus::LookAndFeelButtons m_landfButtons; - Virus::CustomLAF m_landfToolTip; + VirusUI::LookAndFeel m_lookAndFeel; + VirusUI::LookAndFeelButtons m_landfButtons; + VirusUI::CustomLAF m_landfToolTip; juce::String m_previousPath; bool m_paramDisplayLocal = false; @@ -116,3 +118,4 @@ private: void mouseWheelMove (const juce::MouseEvent &event, const juce::MouseWheelDetails &wheel) override; }; +} // namespace Trancy +\ No newline at end of file diff --git a/source/jucePlugin/ui2/Virus_Buttons.cpp b/source/jucePlugin/ui2/Virus_Buttons.cpp @@ -2,116 +2,121 @@ #include "BinaryData.h" #include "Virus_LookAndFeel.h" -using namespace juce; - -namespace Buttons +namespace Trancy { + using namespace juce; - Buttons::Button1::Button1() : DrawableButton("Button1", DrawableButton::ImageRaw) + namespace Buttons { - auto off = Drawable::createFromImageData(BinaryData::btn_1_png, BinaryData::btn_1_pngSize); - auto on = off->createCopy(); - on->setOriginWithOriginalSize({0, 2}); - setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); - setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); - setClickingTogglesState(true); - on->setOriginWithOriginalSize({0, -kHeight}); - setImages(off.get(), nullptr, on.get(), nullptr, on.get()); - } - Buttons::Button2::Button2() : DrawableButton("Button2", DrawableButton::ImageRaw) - { - auto off = Drawable::createFromImageData(BinaryData::btn_2_png, BinaryData::btn_2_pngSize); - auto on = off->createCopy(); - on->setOriginWithOriginalSize({0, 2}); - setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); - setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); - setClickingTogglesState(true); - on->setOriginWithOriginalSize({0, -kHeight}); - setImages(off.get(), nullptr, on.get(), nullptr, on.get()); - } + Buttons::Button1::Button1() : DrawableButton("Button1", DrawableButton::ImageRaw) + { + auto off = Drawable::createFromImageData(BinaryData::btn_1_png, BinaryData::btn_1_pngSize); + auto on = off->createCopy(); + on->setOriginWithOriginalSize({0, 2}); + setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); + setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); + setClickingTogglesState(true); + on->setOriginWithOriginalSize({0, -kHeight}); + setImages(off.get(), nullptr, on.get(), nullptr, on.get()); + } - Buttons::Button3::Button3() : DrawableButton("Button3", DrawableButton::ImageRaw) - { - auto off = Drawable::createFromImageData(BinaryData::btn_3_png, BinaryData::btn_3_pngSize); - auto on = off->createCopy(); - on->setOriginWithOriginalSize({0, 2}); - setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); - setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); - setClickingTogglesState(true); - on->setOriginWithOriginalSize({0, -kHeight}); - setImages(off.get(), nullptr, on.get(), nullptr, on.get()); - } + Buttons::Button2::Button2() : DrawableButton("Button2", DrawableButton::ImageRaw) + { + auto off = Drawable::createFromImageData(BinaryData::btn_2_png, BinaryData::btn_2_pngSize); + auto on = off->createCopy(); + on->setOriginWithOriginalSize({0, 2}); + setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); + setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); + setClickingTogglesState(true); + on->setOriginWithOriginalSize({0, -kHeight}); + setImages(off.get(), nullptr, on.get(), nullptr, on.get()); + } - Buttons::Button4::Button4() : DrawableButton("Button4", DrawableButton::ImageRaw) - { - auto off = Drawable::createFromImageData(BinaryData::btn_4_png, BinaryData::btn_4_pngSize); - auto on = off->createCopy(); - on->setOriginWithOriginalSize({0, 2}); - setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); - setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); - setClickingTogglesState(true); - on->setOriginWithOriginalSize({0, -kHeight}); - setImages(off.get(), nullptr, on.get(), nullptr, on.get()); - } - - Buttons::ButtonMenu::ButtonMenu() : DrawableButton("ButtonMenu", DrawableButton::ImageRaw) - { - auto normal = Drawable::createFromImageData(BinaryData::btn_menu_png, BinaryData::btn_menu_pngSize); - auto pressed = normal->createCopy(); - pressed->setOriginWithOriginalSize({0, 2}); - setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); - setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); - setImages(normal.get(), nullptr, pressed.get(), nullptr, pressed.get(), nullptr, normal.get()); - } + Buttons::Button3::Button3() : DrawableButton("Button3", DrawableButton::ImageRaw) + { + auto off = Drawable::createFromImageData(BinaryData::btn_3_png, BinaryData::btn_3_pngSize); + auto on = off->createCopy(); + on->setOriginWithOriginalSize({0, 2}); + setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); + setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); + setClickingTogglesState(true); + on->setOriginWithOriginalSize({0, -kHeight}); + setImages(off.get(), nullptr, on.get(), nullptr, on.get()); + } + + Buttons::Button4::Button4() : DrawableButton("Button4", DrawableButton::ImageRaw) + { + auto off = Drawable::createFromImageData(BinaryData::btn_4_png, BinaryData::btn_4_pngSize); + auto on = off->createCopy(); + on->setOriginWithOriginalSize({0, 2}); + setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); + setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); + setClickingTogglesState(true); + on->setOriginWithOriginalSize({0, -kHeight}); + setImages(off.get(), nullptr, on.get(), nullptr, on.get()); + } + + Buttons::ButtonMenu::ButtonMenu() : DrawableButton("ButtonMenu", DrawableButton::ImageRaw) + { + auto normal = Drawable::createFromImageData(BinaryData::btn_menu_png, BinaryData::btn_menu_pngSize); + auto pressed = normal->createCopy(); + pressed->setOriginWithOriginalSize({0, 2}); + setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); + setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); + setImages(normal.get(), nullptr, pressed.get(), nullptr, pressed.get(), nullptr, normal.get()); + } - Buttons::PresetButtonLeft::PresetButtonLeft() : DrawableButton("PresetButtonLeft", DrawableButton::ImageRaw) - { - auto normal = Drawable::createFromImageData(BinaryData::btn_left_png, BinaryData::btn_left_pngSize); - auto pressed = normal->createCopy(); - pressed->setOriginWithOriginalSize({0, 2}); - setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); - setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); - setImages(normal.get(), nullptr, pressed.get(), nullptr, pressed.get(), nullptr, normal.get()); - } + Buttons::PresetButtonLeft::PresetButtonLeft() : DrawableButton("PresetButtonLeft", DrawableButton::ImageRaw) + { + auto normal = Drawable::createFromImageData(BinaryData::btn_left_png, BinaryData::btn_left_pngSize); + auto pressed = normal->createCopy(); + pressed->setOriginWithOriginalSize({0, 2}); + setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); + setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); + setImages(normal.get(), nullptr, pressed.get(), nullptr, pressed.get(), nullptr, normal.get()); + } - Buttons::PresetButtonRight::PresetButtonRight() : DrawableButton("PresetButtonLeft", DrawableButton::ImageRaw) - { - auto normal = Drawable::createFromImageData(BinaryData::btn_right_png, BinaryData::btn_right_pngSize); - auto pressed = normal->createCopy(); - pressed->setOriginWithOriginalSize({0, 2}); - setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); - setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); - setImages(normal.get(), nullptr, pressed.get(), nullptr, pressed.get(), nullptr, normal.get()); - } + Buttons::PresetButtonRight::PresetButtonRight() : DrawableButton("PresetButtonLeft", DrawableButton::ImageRaw) + { + auto normal = Drawable::createFromImageData(BinaryData::btn_right_png, BinaryData::btn_right_pngSize); + auto pressed = normal->createCopy(); + pressed->setOriginWithOriginalSize({0, 2}); + setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); + setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); + setImages(normal.get(), nullptr, pressed.get(), nullptr, pressed.get(), nullptr, normal.get()); + } - Buttons::PresetButtonDown::PresetButtonDown() : DrawableButton("PresetButtonDown", DrawableButton::ImageRaw) - { - auto normal = Drawable::createFromImageData(BinaryData::btn_down_png, BinaryData::btn_down_pngSize); - auto pressed = normal->createCopy(); - pressed->setOriginWithOriginalSize({0, 2}); - setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); - setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); - setImages(normal.get(), nullptr, pressed.get(), nullptr, pressed.get(), nullptr, normal.get()); - } + Buttons::PresetButtonDown::PresetButtonDown() : DrawableButton("PresetButtonDown", DrawableButton::ImageRaw) + { + auto normal = Drawable::createFromImageData(BinaryData::btn_down_png, BinaryData::btn_down_pngSize); + auto pressed = normal->createCopy(); + pressed->setOriginWithOriginalSize({0, 2}); + setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); + setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); + setImages(normal.get(), nullptr, pressed.get(), nullptr, pressed.get(), nullptr, normal.get()); + } - Buttons::OptionButtonLoadBank::OptionButtonLoadBank() : DrawableButton("LoadBank", DrawableButton::ImageRaw) - { - auto normal = Drawable::createFromImageData(BinaryData::btn_load_bank_png, BinaryData::btn_load_bank_pngSize); - auto pressed = normal->createCopy(); - pressed->setOriginWithOriginalSize({0, 2}); - setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); - setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); - setImages(normal.get(), nullptr, pressed.get(), nullptr, pressed.get(), nullptr, normal.get()); - } + Buttons::OptionButtonLoadBank::OptionButtonLoadBank() : DrawableButton("LoadBank", DrawableButton::ImageRaw) + { + auto normal = + Drawable::createFromImageData(BinaryData::btn_load_bank_png, BinaryData::btn_load_bank_pngSize); + auto pressed = normal->createCopy(); + pressed->setOriginWithOriginalSize({0, 2}); + setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); + setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); + setImages(normal.get(), nullptr, pressed.get(), nullptr, pressed.get(), nullptr, normal.get()); + } - Buttons::OptionButtonSavePreset::OptionButtonSavePreset() : DrawableButton("LoadBank", DrawableButton::ImageRaw) - { - auto normal = Drawable::createFromImageData(BinaryData::btn_save_preset_png, BinaryData::btn_save_preset_pngSize); - auto pressed = normal->createCopy(); - pressed->setOriginWithOriginalSize({0, 2}); - setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); - setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); - setImages(normal.get(), nullptr, pressed.get(), nullptr, pressed.get(), nullptr, normal.get()); - } -}; // namespace Buttons + Buttons::OptionButtonSavePreset::OptionButtonSavePreset() : DrawableButton("LoadBank", DrawableButton::ImageRaw) + { + auto normal = + Drawable::createFromImageData(BinaryData::btn_save_preset_png, BinaryData::btn_save_preset_pngSize); + auto pressed = normal->createCopy(); + pressed->setOriginWithOriginalSize({0, 2}); + setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); + setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); + setImages(normal.get(), nullptr, pressed.get(), nullptr, pressed.get(), nullptr, normal.get()); + } + }; // namespace Buttons +} // namespace Trancy +\ No newline at end of file diff --git a/source/jucePlugin/ui2/Virus_Buttons.h b/source/jucePlugin/ui2/Virus_Buttons.h @@ -1,87 +1,91 @@ #pragma once #include <juce_gui_extra/juce_gui_extra.h> - -namespace Buttons +namespace Trancy { - class Button1 : public juce::DrawableButton - { - public: - Button1(); - static constexpr auto kWidth = 36; - static constexpr auto kHeight = 136/2; - }; - class Button2 : public juce::DrawableButton + namespace Buttons { - public: - Button2(); - static constexpr auto kWidth = 69; - static constexpr auto kHeight = 134/2; - }; + class Button1 : public juce::DrawableButton + { + public: + Button1(); + static constexpr auto kWidth = 36; + static constexpr auto kHeight = 136 / 2; + }; - class Button3 : public juce::DrawableButton - { - public: - Button3(); - static constexpr auto kWidth = 69; - static constexpr auto kHeight = 134/2; - }; + class Button2 : public juce::DrawableButton + { + public: + Button2(); + static constexpr auto kWidth = 69; + static constexpr auto kHeight = 134 / 2; + }; - class Button4 : public juce::DrawableButton - { - public: - Button4(); - static constexpr auto kWidth = 68; - static constexpr auto kHeight = 72/2; - }; + class Button3 : public juce::DrawableButton + { + public: + Button3(); + static constexpr auto kWidth = 69; + static constexpr auto kHeight = 134 / 2; + }; - class ButtonMenu: public juce::DrawableButton - { - public: - static constexpr auto kWidth = 172; - static constexpr auto kHeight = 51; - ButtonMenu(); - }; + class Button4 : public juce::DrawableButton + { + public: + Button4(); + static constexpr auto kWidth = 68; + static constexpr auto kHeight = 72 / 2; + }; - class PresetButtonLeft: public juce::DrawableButton - { - public: - static constexpr auto kWidth = 33; - static constexpr auto kHeight = 51; - PresetButtonLeft(); - }; + class ButtonMenu : public juce::DrawableButton + { + public: + static constexpr auto kWidth = 172; + static constexpr auto kHeight = 51; + ButtonMenu(); + }; - class PresetButtonRight: public juce::DrawableButton - { - public: - static constexpr auto kWidth = 33; - static constexpr auto kHeight = 51; - PresetButtonRight(); - }; + class PresetButtonLeft : public juce::DrawableButton + { + public: + static constexpr auto kWidth = 33; + static constexpr auto kHeight = 51; + PresetButtonLeft(); + }; - class PresetButtonDown: public juce::DrawableButton - { - public: - static constexpr auto kWidth = 33; - static constexpr auto kHeight = 51; - PresetButtonDown(); - }; - - class OptionButtonLoadBank: public juce::DrawableButton - { - public: - static constexpr auto kWidth = 172; - static constexpr auto kHeight = 50; - OptionButtonLoadBank(); - }; + class PresetButtonRight : public juce::DrawableButton + { + public: + static constexpr auto kWidth = 33; + static constexpr auto kHeight = 51; + PresetButtonRight(); + }; - class OptionButtonSavePreset: public juce::DrawableButton - { - public: - static constexpr auto kWidth = 172; - static constexpr auto kHeight = 50; - OptionButtonSavePreset(); - }; + class PresetButtonDown : public juce::DrawableButton + { + public: + static constexpr auto kWidth = 33; + static constexpr auto kHeight = 51; + PresetButtonDown(); + }; + + class OptionButtonLoadBank : public juce::DrawableButton + { + public: + static constexpr auto kWidth = 172; + static constexpr auto kHeight = 50; + OptionButtonLoadBank(); + }; + + class OptionButtonSavePreset : public juce::DrawableButton + { + public: + static constexpr auto kWidth = 172; + static constexpr auto kHeight = 50; + OptionButtonSavePreset(); + }; + + } // namespace Buttons -} // namespace Buttons +} // namespace Trancy +\ No newline at end of file diff --git a/source/jucePlugin/ui2/Virus_LookAndFeel.cpp b/source/jucePlugin/ui2/Virus_LookAndFeel.cpp @@ -1,82 +1,85 @@ #include "Virus_LookAndFeel.h" #include "BinaryData.h" - -using namespace juce; - -namespace Virus +namespace Trancy { - const Font getCustomFont() - { - static auto typefaceDigiFont = Typeface::createSystemTypefaceFor(BinaryData::Digital, BinaryData::DigitalSize); - return Font (typefaceDigiFont); - } - - //LookAndFeel - LookAndFeelSmallButton::LookAndFeelSmallButton() - { - // setup knobs... - m_genKnob = Drawable::createFromImageData(BinaryData::knob_2_128_png, BinaryData::knob_2_128_pngSize); - - m_knobImageSteps.start = 1; - m_knobImageSteps.end = 127; - } - - void LookAndFeelSmallButton::drawRotarySlider(Graphics &g, int x, int y, int width, int height, float sliderPosProportional, - float rotaryStartAngle, float rotaryEndAngle, Slider &s) - { - Drawable *knob = m_genKnob.get(); - int step; - (s.isEnabled())?step=roundToInt(m_knobImageSteps.convertFrom0to1(sliderPosProportional)):step=0; + using namespace juce; - knob->setOriginWithOriginalSize({0.0f, -float(kKnobSize) * step}); - - // this won't support scaling! - knob->drawAt(g, x, y, 1.0f); - } - - LookAndFeel::LookAndFeel() - { - // setup knobs... - m_genKnob = Drawable::createFromImageData(BinaryData::knob_1_128_png, BinaryData::knob_1_128_pngSize); - - m_knobImageSteps.start = 1; - m_knobImageSteps.end = 127; - } - - void LookAndFeel::drawRotarySlider(Graphics &g, int x, int y, int width, int height, float sliderPosProportional, - float rotaryStartAngle, float rotaryEndAngle, Slider &s) - { - Drawable *knob = m_genKnob.get(); - - int step; - (s.isEnabled())?step=roundToInt(m_knobImageSteps.convertFrom0to1(sliderPosProportional)):step=0; - - knob->setOriginWithOriginalSize({0.0f, -float(kKnobSize) * step}); - - // this won't support scaling! - knob->drawAt(g, x, y, 1.0f); - } - - void LookAndFeel::drawComboBox (Graphics& gGrafik, int width, int height, bool isButtonDown, int buttonX, int buttonY, int buttonW, int buttonH, ComboBox& box) - { - //gGrafik.setOpacity(0); - //box.setColour(ComboBox::textColourId, Colours::red); - }; - - //LookAndFeelPatchBrowser - LookAndFeelPatchBrowser::LookAndFeelPatchBrowser() - { - } - - //LookAndFeelButtons - LookAndFeelButtons::LookAndFeelButtons() + namespace VirusUI { - } - - void LookAndFeelButtons::drawComboBox (Graphics& gGrafik, int width, int height, bool isButtonDown, int buttonX, int buttonY, int buttonW, int buttonH, ComboBox& box) - { - gGrafik.setOpacity(0); - }; - -} // namespace Virus + const Font getCustomFont() + { + static auto typefaceDigiFont = + Typeface::createSystemTypefaceFor(BinaryData::Digital, BinaryData::DigitalSize); + return Font(typefaceDigiFont); + } + + // LookAndFeel + LookAndFeelSmallButton::LookAndFeelSmallButton() + { + // setup knobs... + m_genKnob = Drawable::createFromImageData(BinaryData::knob_2_128_png, BinaryData::knob_2_128_pngSize); + + m_knobImageSteps.start = 1; + m_knobImageSteps.end = 127; + } + + void LookAndFeelSmallButton::drawRotarySlider(Graphics &g, int x, int y, int width, int height, + float sliderPosProportional, float rotaryStartAngle, + float rotaryEndAngle, Slider &s) + { + Drawable *knob = m_genKnob.get(); + + int step; + (s.isEnabled()) ? step = roundToInt(m_knobImageSteps.convertFrom0to1(sliderPosProportional)) : step = 0; + + knob->setOriginWithOriginalSize({0.0f, -float(kKnobSize) * step}); + + // this won't support scaling! + knob->drawAt(g, x, y, 1.0f); + } + + LookAndFeel::LookAndFeel() + { + // setup knobs... + m_genKnob = Drawable::createFromImageData(BinaryData::knob_1_128_png, BinaryData::knob_1_128_pngSize); + + m_knobImageSteps.start = 1; + m_knobImageSteps.end = 127; + } + + void LookAndFeel::drawRotarySlider(Graphics &g, int x, int y, int width, int height, + float sliderPosProportional, float rotaryStartAngle, float rotaryEndAngle, + Slider &s) + { + Drawable *knob = m_genKnob.get(); + + int step; + (s.isEnabled()) ? step = roundToInt(m_knobImageSteps.convertFrom0to1(sliderPosProportional)) : step = 0; + + knob->setOriginWithOriginalSize({0.0f, -float(kKnobSize) * step}); + + // this won't support scaling! + knob->drawAt(g, x, y, 1.0f); + } + + void LookAndFeel::drawComboBox(Graphics &gGrafik, int width, int height, bool isButtonDown, int buttonX, + int buttonY, int buttonW, int buttonH, ComboBox &box){ + // gGrafik.setOpacity(0); + // box.setColour(ComboBox::textColourId, Colours::red); + }; + + // LookAndFeelPatchBrowser + LookAndFeelPatchBrowser::LookAndFeelPatchBrowser() {} + + // LookAndFeelButtons + LookAndFeelButtons::LookAndFeelButtons() {} + + void LookAndFeelButtons::drawComboBox(Graphics &gGrafik, int width, int height, bool isButtonDown, int buttonX, + int buttonY, int buttonW, int buttonH, ComboBox &box) + { + gGrafik.setOpacity(0); + }; + + } // namespace Virus +} // namespace Trancy +\ No newline at end of file diff --git a/source/jucePlugin/ui2/Virus_LookAndFeel.h b/source/jucePlugin/ui2/Virus_LookAndFeel.h @@ -1,152 +1,140 @@ #pragma once #include <juce_gui_extra/juce_gui_extra.h> +namespace Trancy +{ -constexpr auto comboBoxHeight = 38; -constexpr auto comboBoxWidth = 126; + constexpr auto comboBoxHeight = 38; + constexpr auto comboBoxWidth = 126; + + constexpr auto comboBox2Height = 52; + constexpr auto comboBox2Width = 74; + + constexpr auto comboBox3Height = 52; + constexpr auto comboBox3Width = 186; -constexpr auto comboBox2Height = 52; -constexpr auto comboBox2Width = 74; + constexpr auto kPanelWidth = 2501; + constexpr auto kPanelHeight = 1152; -constexpr auto comboBox3Height = 52; -constexpr auto comboBox3Width = 186; + constexpr auto comboBoxXMargin = 5; -constexpr auto kPanelWidth = 2501; -constexpr auto kPanelHeight = 1152; + namespace VirusUI + { + const juce::Font getCustomFont(); -constexpr auto comboBoxXMargin = 5; + class CustomLAF : public juce::LookAndFeel_V4 + { + public: + void drawLabel(juce::Graphics &g, juce::Label &l) override + { + // g.fillAll (label.findColour (Label::backgroundColourId)); + g.setColour(l.findColour(juce::Label::backgroundColourId)); + g.fillRoundedRectangle(l.getLocalBounds().toFloat(), 5); -namespace Virus -{ - const juce::Font getCustomFont(); - - class CustomLAF : public juce::LookAndFeel_V4 - { - public: - void drawLabel(juce::Graphics& g, juce::Label& l) override - { - // g.fillAll (label.findColour (Label::backgroundColourId)); - g.setColour (l.findColour (juce::Label::backgroundColourId)); - g.fillRoundedRectangle (l.getLocalBounds().toFloat(), 5); - - // g.drawRect (label.getLocalBounds()); - g.drawRoundedRectangle (l.getLocalBounds().toFloat(), 10, 1); - } - juce::Font getLabelFont(juce::Label& label) override - { - juce::Font fFont(getCustomFont().getTypeface()); - fFont.setHeight(20.f); - return fFont; - } - }; - - class LookAndFeelSmallButton : public juce::LookAndFeel_V4/*, juce::Slider*/ - { - public: - LookAndFeelSmallButton(); - - static constexpr auto kKnobSize = 55; - static const char *KnobStyleProp; - - void drawRotarySlider(juce::Graphics &, int x, int y, int width, int height, float sliderPosProportional, - float rotaryStartAngle, float rotaryEndAngle, juce::Slider &sSlider) override; - - - private: - std::unique_ptr<juce::Drawable> m_genKnob; - juce::NormalisableRange<float> m_knobImageSteps; - }; - - - class LookAndFeel : public juce::LookAndFeel_V4/*, juce::Slider*/ - { - public: - LookAndFeel(); - - static constexpr auto kKnobSize = 75; - static const char *KnobStyleProp; - - void drawRotarySlider(juce::Graphics &, int x, int y, int width, int height, float sliderPosProportional, - float rotaryStartAngle, float rotaryEndAngle, juce::Slider &sSlider) override; - - - juce::Typeface::Ptr getTypefaceForFont (const juce::Font& f) override - { - return getCustomFont().getTypeface(); - } - - void drawComboBox (juce::Graphics& gGrafik, int width, int height, bool isButtonDown, int buttonX, int buttonY, int buttonW, int buttonH, juce::ComboBox& box) override; - - juce::Font getComboBoxFont (juce::ComboBox& ) override - { - juce::Font fFont(getCustomFont().getTypeface()); - fFont.setHeight(20.f); - return fFont; - } - - juce::Font getTextButtonFont(juce::TextButton& button, int buttonHeight) override - { - juce::Font fFont(getCustomFont().getTypeface()); - fFont.setHeight(20.f); - return fFont; - } - - juce::Font getPopupMenuFont() override - { - juce::Font fFont(getCustomFont().getTypeface()); - fFont.setHeight(20.f); - return fFont; - } - - private: - std::unique_ptr<juce::Drawable> m_genKnob; - juce::NormalisableRange<float> m_knobImageSteps; - }; - - class LookAndFeelPatchBrowser : public juce::LookAndFeel_V4 - { - public: - LookAndFeelPatchBrowser(); - - juce::Font getComboBoxFont (juce::ComboBox& /*box*/) override - { - return getCommonMenuFont(); - } - - juce::Font getPopupMenuFont() override - { - return getCommonMenuFont(); - } - - private: - juce::Font getCommonMenuFont() - { - return juce::Font("Arial", "Normal", 13.f); - } - }; - - class LookAndFeelButtons : public juce::LookAndFeel_V4 - { - public: - LookAndFeelButtons(); - - juce::Font getComboBoxFont (juce::ComboBox& /*box*/) override - { - return getCommonMenuFont(); - } - - juce::Font getPopupMenuFont() override - { - return getCommonMenuFont(); - } - - void drawComboBox (juce::Graphics& gGrafik, int width, int height, bool isButtonDown, int buttonX, int buttonY, int buttonW, int buttonH, juce::ComboBox& box) override; - - private: - juce::Font getCommonMenuFont() - { - return juce::Font("Arial", "Normal", 23.f); - } - }; - -} // namespace Virus + // g.drawRect (label.getLocalBounds()); + g.drawRoundedRectangle(l.getLocalBounds().toFloat(), 10, 1); + } + juce::Font getLabelFont(juce::Label &label) override + { + juce::Font fFont(getCustomFont().getTypeface()); + fFont.setHeight(20.f); + return fFont; + } + }; + + class LookAndFeelSmallButton : public juce::LookAndFeel_V4 /*, juce::Slider*/ + { + public: + LookAndFeelSmallButton(); + + static constexpr auto kKnobSize = 55; + static const char *KnobStyleProp; + + void drawRotarySlider(juce::Graphics &, int x, int y, int width, int height, float sliderPosProportional, + float rotaryStartAngle, float rotaryEndAngle, juce::Slider &sSlider) override; + + + private: + std::unique_ptr<juce::Drawable> m_genKnob; + juce::NormalisableRange<float> m_knobImageSteps; + }; + + + class LookAndFeel : public juce::LookAndFeel_V4 /*, juce::Slider*/ + { + public: + LookAndFeel(); + + static constexpr auto kKnobSize = 75; + static const char *KnobStyleProp; + + void drawRotarySlider(juce::Graphics &, int x, int y, int width, int height, float sliderPosProportional, + float rotaryStartAngle, float rotaryEndAngle, juce::Slider &sSlider) override; + + + juce::Typeface::Ptr getTypefaceForFont(const juce::Font &f) override + { + return getCustomFont().getTypeface(); + } + + void drawComboBox(juce::Graphics &gGrafik, int width, int height, bool isButtonDown, int buttonX, + int buttonY, int buttonW, int buttonH, juce::ComboBox &box) override; + + juce::Font getComboBoxFont(juce::ComboBox &) override + { + juce::Font fFont(getCustomFont().getTypeface()); + fFont.setHeight(20.f); + return fFont; + } + + juce::Font getTextButtonFont(juce::TextButton &button, int buttonHeight) override + { + juce::Font fFont(getCustomFont().getTypeface()); + fFont.setHeight(20.f); + return fFont; + } + + juce::Font getPopupMenuFont() override + { + juce::Font fFont(getCustomFont().getTypeface()); + fFont.setHeight(20.f); + return fFont; + } + + private: + std::unique_ptr<juce::Drawable> m_genKnob; + juce::NormalisableRange<float> m_knobImageSteps; + }; + + class LookAndFeelPatchBrowser : public juce::LookAndFeel_V4 + { + public: + LookAndFeelPatchBrowser(); + + juce::Font getComboBoxFont(juce::ComboBox & /*box*/) override { return getCommonMenuFont(); } + + juce::Font getPopupMenuFont() override { return getCommonMenuFont(); } + + private: + juce::Font getCommonMenuFont() { return juce::Font("Arial", "Normal", 13.f); } + }; + + class LookAndFeelButtons : public juce::LookAndFeel_V4 + { + public: + LookAndFeelButtons(); + + juce::Font getComboBoxFont(juce::ComboBox & /*box*/) override { return getCommonMenuFont(); } + + juce::Font getPopupMenuFont() override { return getCommonMenuFont(); } + + void drawComboBox(juce::Graphics &gGrafik, int width, int height, bool isButtonDown, int buttonX, + int buttonY, int buttonW, int buttonH, juce::ComboBox &box) override; + + private: + juce::Font getCommonMenuFont() { return juce::Font("Arial", "Normal", 23.f); } + }; + + } // namespace Virus + +} // namespace Trancy +\ No newline at end of file diff --git a/source/jucePlugin/ui2/Virus_Panel1_OscEditor.cpp b/source/jucePlugin/ui2/Virus_Panel1_OscEditor.cpp @@ -2,271 +2,289 @@ #include "BinaryData.h" #include "Ui_Utils.h" #include "../VirusParameterBinding.h" - -using namespace juce; - -OscEditor::OscEditor(VirusParameterBinding& _parameterBinding) +class VirusParameterBinding; +using namespace Virus; +namespace Trancy { - setupBackground(*this, m_background, BinaryData::panel_1_png, BinaryData::panel_1_pngSize); - setBounds(m_background->getDrawableBounds().toNearestIntEdges()); - - //setLookAndFeel(&m_lookAndFeel); - - for (auto *s : {&m_osc1Shape, &m_osc1PulseWidth, &m_osc1Semitone, &m_osc1KeyFollow}) - { - setupRotary(*this, *s); - } - - //OSC 1 - m_osc1Shape.setBounds(287 - knobSize / 2, 103 - knobSize / 2, knobSize, knobSize); - m_osc1PulseWidth.setBounds(433 - knobSize / 2, 103 - knobSize / 2, knobSize, knobSize); - m_osc1Semitone.setBounds(577 - knobSize / 2, 103 - knobSize / 2, knobSize, knobSize); - m_osc1KeyFollow.setBounds(722 - knobSize / 2, 103 - knobSize / 2, knobSize, knobSize); - - addAndMakeVisible(m_osc1WaveSelect); - m_osc1WaveSelect.setBounds(114+comboBoxXMargin - comboBoxWidth / 2, 103 - comboBoxHeight / 2, comboBoxWidth, comboBoxHeight); - - _parameterBinding.bind(m_osc1Semitone, Virus::Param_Osc1Semitone); - _parameterBinding.bind(m_osc1Shape, Virus::Param_Osc1Shape); - _parameterBinding.bind(m_osc1PulseWidth, Virus::Param_Osc1PW ); - _parameterBinding.bind(m_osc1KeyFollow, Virus::Param_Osc1Keyfollow ); - _parameterBinding.bind(m_osc1WaveSelect, Virus::Param_Osc1Wave); - - //OSC 2 - for (auto *s : {&m_osc2Shape, &m_osc2PulseWidth, &m_osc2Semitone, &m_osc2KeyFollow}) - { - setupRotary(*this, *s); - } - - m_osc2Shape.setBounds(287 - knobSize / 2, 311 - knobSize / 2, knobSize, knobSize); - m_osc2PulseWidth.setBounds(433 - knobSize / 2, 311 - knobSize / 2, knobSize, knobSize); - m_osc2Semitone.setBounds(577 - knobSize / 2, 311 - knobSize / 2, knobSize, knobSize); - m_osc2KeyFollow.setBounds(722 - knobSize / 2, 311 - knobSize / 2, knobSize, knobSize); - - addAndMakeVisible(m_osc2WaveSelect); - m_osc2WaveSelect.setBounds(114+comboBoxXMargin - comboBoxWidth / 2, 311 - comboBoxHeight / 2, comboBoxWidth, comboBoxHeight); - - for (auto *s : {&m_osc2FmAmount, &m_osc2Detune, &m_osc2EnvFm, &m_osc2envOSC, &m_osc2PhaseInit}) - { - setupRotary(*this, *s); - } - - m_osc2FmAmount.setBounds(287 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); - m_osc2Detune.setBounds(433 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); - m_osc2EnvFm.setBounds(577 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); - m_osc2envOSC.setBounds(722 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); - m_osc2PhaseInit.setBounds(871 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); - - addAndMakeVisible(m_osc2FmMode); - m_osc2FmMode.setBounds(114+comboBoxXMargin - comboBoxWidth / 2, 485 - comboBoxHeight / 2, comboBoxWidth, comboBoxHeight); - - addAndMakeVisible(m_syncOsc1Osc2); - m_syncOsc1Osc2.setBounds(871 - m_syncOsc1Osc2.kWidth/ 2, 308 - m_syncOsc1Osc2.kHeight / 2, m_syncOsc1Osc2.kWidth, m_syncOsc1Osc2.kHeight); - - _parameterBinding.bind(m_osc2Semitone, Virus::Param_Osc2Semitone); - _parameterBinding.bind(m_osc2Shape, Virus::Param_Osc2Shape); - _parameterBinding.bind(m_osc2PulseWidth, Virus::Param_Osc2PW); - _parameterBinding.bind(m_osc2KeyFollow, Virus::Param_Osc2Keyfollow); - _parameterBinding.bind(m_osc2WaveSelect, Virus::Param_Osc2Wave); - - _parameterBinding.bind(m_osc2FmAmount, Virus::Param_Osc2FMAmount); - _parameterBinding.bind(m_osc2Detune, Virus::Param_Osc2Detune); - _parameterBinding.bind(m_osc2EnvFm, Virus::Param_FMFiltEnvAmt); - _parameterBinding.bind(m_osc2envOSC, Virus::Param_Osc2FltEnvAmt); - _parameterBinding.bind(m_osc2PhaseInit, Virus::Param_OscInitPhase); - _parameterBinding.bind(m_osc2FmMode, Virus::Param_OscFMMode); - _parameterBinding.bind(m_syncOsc1Osc2, Virus::Param_Osc2Sync); - - //OSC 3 - for (auto *s : {&m_osc3Semitone, &m_osc3Detune, &m_osc3Level}) - { - setupRotary(*this, *s); - } - - m_osc3Semitone.setBounds(287 - knobSize / 2, 694 - knobSize / 2, knobSize, knobSize); - m_osc3Detune.setBounds(434 - knobSize / 2, 694 - knobSize / 2, knobSize, knobSize); - m_osc3Mode.setBounds(114+comboBoxXMargin - comboBoxWidth / 2, 694 - comboBoxHeight / 2, comboBoxWidth, comboBoxHeight); - addAndMakeVisible(m_osc3Mode); - - _parameterBinding.bind(m_osc3Semitone, Virus::Param_Osc3Semitone); - _parameterBinding.bind(m_osc3Detune, Virus::Param_Osc3Detune); - _parameterBinding.bind(m_osc3Mode, Virus::Param_Osc3Mode); - - // OSC SUB - setupRotary(*this, m_noiseColor); - m_noiseColor.setBounds(841 - knobSize / 2, 695 - knobSize / 2, knobSize, knobSize); - m_subWaveform.setBounds(656 - m_subWaveform.kWidth / 2, 692 - m_subWaveform.kHeight / 2, m_subWaveform.kWidth, m_subWaveform.kHeight); - addAndMakeVisible(m_subWaveform); - _parameterBinding.bind(m_noiseColor, Virus::Param_NoiseColor); - _parameterBinding.bind(m_subWaveform, Virus::Param_SubOscShape); - - //UNISON - for (auto *s : {&m_detune, &m_panSpread, &m_lfoPhase}) + using namespace juce; + using namespace Virus; + OscEditor::OscEditor(VirusParameterBinding &_parameterBinding) { - setupRotary(*this, *s); + setupBackground(*this, m_background, BinaryData::panel_1_png, BinaryData::panel_1_pngSize); + setBounds(m_background->getDrawableBounds().toNearestIntEdges()); + + // setLookAndFeel(&m_lookAndFeel); + + for (auto *s : {&m_osc1Shape, &m_osc1PulseWidth, &m_osc1Semitone, &m_osc1KeyFollow}) + { + setupRotary(*this, *s); + } + + // OSC 1 + m_osc1Shape.setBounds(287 - knobSize / 2, 103 - knobSize / 2, knobSize, knobSize); + m_osc1PulseWidth.setBounds(433 - knobSize / 2, 103 - knobSize / 2, knobSize, knobSize); + m_osc1Semitone.setBounds(577 - knobSize / 2, 103 - knobSize / 2, knobSize, knobSize); + m_osc1KeyFollow.setBounds(722 - knobSize / 2, 103 - knobSize / 2, knobSize, knobSize); + + addAndMakeVisible(m_osc1WaveSelect); + m_osc1WaveSelect.setBounds(114 + comboBoxXMargin - comboBoxWidth / 2, 103 - comboBoxHeight / 2, comboBoxWidth, + comboBoxHeight); + + _parameterBinding.bind(m_osc1Semitone, Virus::Param_Osc1Semitone); + _parameterBinding.bind(m_osc1Shape, Virus::Param_Osc1Shape); + _parameterBinding.bind(m_osc1PulseWidth, Virus::Param_Osc1PW); + _parameterBinding.bind(m_osc1KeyFollow, Virus::Param_Osc1Keyfollow); + _parameterBinding.bind(m_osc1WaveSelect, Virus::Param_Osc1Wave); + + // OSC 2 + for (auto *s : {&m_osc2Shape, &m_osc2PulseWidth, &m_osc2Semitone, &m_osc2KeyFollow}) + { + setupRotary(*this, *s); + } + + m_osc2Shape.setBounds(287 - knobSize / 2, 311 - knobSize / 2, knobSize, knobSize); + m_osc2PulseWidth.setBounds(433 - knobSize / 2, 311 - knobSize / 2, knobSize, knobSize); + m_osc2Semitone.setBounds(577 - knobSize / 2, 311 - knobSize / 2, knobSize, knobSize); + m_osc2KeyFollow.setBounds(722 - knobSize / 2, 311 - knobSize / 2, knobSize, knobSize); + + addAndMakeVisible(m_osc2WaveSelect); + m_osc2WaveSelect.setBounds(114 + comboBoxXMargin - comboBoxWidth / 2, 311 - comboBoxHeight / 2, comboBoxWidth, + comboBoxHeight); + + for (auto *s : {&m_osc2FmAmount, &m_osc2Detune, &m_osc2EnvFm, &m_osc2envOSC, &m_osc2PhaseInit}) + { + setupRotary(*this, *s); + } + + m_osc2FmAmount.setBounds(287 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); + m_osc2Detune.setBounds(433 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); + m_osc2EnvFm.setBounds(577 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); + m_osc2envOSC.setBounds(722 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); + m_osc2PhaseInit.setBounds(871 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); + + addAndMakeVisible(m_osc2FmMode); + m_osc2FmMode.setBounds(114 + comboBoxXMargin - comboBoxWidth / 2, 485 - comboBoxHeight / 2, comboBoxWidth, + comboBoxHeight); + + addAndMakeVisible(m_syncOsc1Osc2); + m_syncOsc1Osc2.setBounds(871 - m_syncOsc1Osc2.kWidth / 2, 308 - m_syncOsc1Osc2.kHeight / 2, + m_syncOsc1Osc2.kWidth, m_syncOsc1Osc2.kHeight); + + _parameterBinding.bind(m_osc2Semitone, Virus::Param_Osc2Semitone); + _parameterBinding.bind(m_osc2Shape, Virus::Param_Osc2Shape); + _parameterBinding.bind(m_osc2PulseWidth, Virus::Param_Osc2PW); + _parameterBinding.bind(m_osc2KeyFollow, Virus::Param_Osc2Keyfollow); + _parameterBinding.bind(m_osc2WaveSelect, Virus::Param_Osc2Wave); + + _parameterBinding.bind(m_osc2FmAmount, Virus::Param_Osc2FMAmount); + _parameterBinding.bind(m_osc2Detune, Virus::Param_Osc2Detune); + _parameterBinding.bind(m_osc2EnvFm, Virus::Param_FMFiltEnvAmt); + _parameterBinding.bind(m_osc2envOSC, Virus::Param_Osc2FltEnvAmt); + _parameterBinding.bind(m_osc2PhaseInit, Virus::Param_OscInitPhase); + _parameterBinding.bind(m_osc2FmMode, Virus::Param_OscFMMode); + _parameterBinding.bind(m_syncOsc1Osc2, Virus::Param_Osc2Sync); + + // OSC 3 + for (auto *s : {&m_osc3Semitone, &m_osc3Detune, &m_osc3Level}) + { + setupRotary(*this, *s); + } + + m_osc3Semitone.setBounds(287 - knobSize / 2, 694 - knobSize / 2, knobSize, knobSize); + m_osc3Detune.setBounds(434 - knobSize / 2, 694 - knobSize / 2, knobSize, knobSize); + m_osc3Mode.setBounds(114 + comboBoxXMargin - comboBoxWidth / 2, 694 - comboBoxHeight / 2, comboBoxWidth, + comboBoxHeight); + addAndMakeVisible(m_osc3Mode); + + _parameterBinding.bind(m_osc3Semitone, Virus::Param_Osc3Semitone); + _parameterBinding.bind(m_osc3Detune, Virus::Param_Osc3Detune); + _parameterBinding.bind(m_osc3Mode, Virus::Param_Osc3Mode); + + // OSC SUB + setupRotary(*this, m_noiseColor); + m_noiseColor.setBounds(841 - knobSize / 2, 695 - knobSize / 2, knobSize, knobSize); + m_subWaveform.setBounds(656 - m_subWaveform.kWidth / 2, 692 - m_subWaveform.kHeight / 2, m_subWaveform.kWidth, + m_subWaveform.kHeight); + addAndMakeVisible(m_subWaveform); + _parameterBinding.bind(m_noiseColor, Virus::Param_NoiseColor); + _parameterBinding.bind(m_subWaveform, Virus::Param_SubOscShape); + + // UNISON + for (auto *s : {&m_detune, &m_panSpread, &m_lfoPhase}) + { + setupRotary(*this, *s); + } + + m_detune.setBounds(287 - knobSize / 2, 903 - knobSize / 2, knobSize, knobSize); + m_panSpread.setBounds(434 - knobSize / 2, 903 - knobSize / 2, knobSize, knobSize); + m_lfoPhase.setBounds(577 - knobSize / 2, 903 - knobSize / 2, knobSize, knobSize); + addAndMakeVisible(m_unisonVoices); + m_unisonVoices.setBounds(114 + comboBoxXMargin - comboBoxWidth / 2, 903 - comboBoxHeight / 2, comboBoxWidth, + comboBoxHeight); + + _parameterBinding.bind(m_detune, Virus::Param_UnisonDetune); + _parameterBinding.bind(m_panSpread, Virus::Param_UnisonPanSpread); + _parameterBinding.bind(m_lfoPhase, Virus::Param_UnisonLfoPhase); + _parameterBinding.bind(m_unisonVoices, Virus::Param_UnisonMode); + + // Punch + setupRotary(*this, m_Punch); + m_Punch.setBounds(841 - knobSize / 2, 903 - knobSize / 2, knobSize, knobSize); + _parameterBinding.bind(m_Punch, Virus::Param_PunchIntensity); + + // Mixer + for (auto *s : {&m_oscBalance, &m_oscLevel, &m_osc3Level, &m_oscSublevel, &m_noiseLevel, &m_ringModLevel}) + { + setupRotary(*this, *s); + } + + m_oscBalance.setBounds(1260 - knobSize / 2, 102 - knobSize / 2, knobSize, knobSize); + m_oscLevel.setBounds(1260 - knobSize / 2, 263 - knobSize / 2, knobSize, knobSize); + m_osc3Level.setBounds(1260 - knobSize / 2, 422 - knobSize / 2, knobSize, knobSize); + m_oscSublevel.setBounds(1260 - knobSize / 2, 579 - knobSize / 2, knobSize, knobSize); + m_noiseLevel.setBounds(1260 - knobSize / 2, 744 - knobSize / 2, knobSize, knobSize); + m_ringModLevel.setBounds(1260 - knobSize / 2, 903 - knobSize / 2, knobSize, knobSize); + + _parameterBinding.bind(m_oscBalance, Virus::Param_OscBalance); + _parameterBinding.bind(m_oscLevel, Virus::Param_OscMainVolume); + _parameterBinding.bind(m_osc3Level, Virus::Param_Osc3Volume); + _parameterBinding.bind(m_oscSublevel, Virus::Param_SubOscVolume); + _parameterBinding.bind(m_noiseLevel, Virus::Param_NoiseVolume); + _parameterBinding.bind(m_ringModLevel, Virus::Param_RingModMVolume); + + // Velo mod + for (auto *s : {&m_osc1ShapeVelocity, &m_pulseWidthVelocity, &m_ampVelocity, &m_panoramaVelocity, + &m_osc2ShapeVelocity, &m_fmAmountVelocity}) + { + setupRotary(*this, *s); + } + + m_osc1ShapeVelocity.setBounds(1067 - knobSize / 2, 102 - knobSize / 2, knobSize, knobSize); + m_osc2ShapeVelocity.setBounds(1067 - knobSize / 2, 264 - knobSize / 2, knobSize, knobSize); + m_pulseWidthVelocity.setBounds(1067 - knobSize / 2, 421 - knobSize / 2, knobSize, knobSize); + m_fmAmountVelocity.setBounds(1067 - knobSize / 2, 579 - knobSize / 2, knobSize, knobSize); + m_ampVelocity.setBounds(1067 - knobSize / 2, 743 - knobSize / 2, knobSize, knobSize); + m_panoramaVelocity.setBounds(1067 - knobSize / 2, 903 - knobSize / 2, knobSize, knobSize); + + _parameterBinding.bind(m_osc1ShapeVelocity, Virus::Param_Osc1ShapeVelocity); + _parameterBinding.bind(m_pulseWidthVelocity, Virus::Param_PulseWidthVelocity); + _parameterBinding.bind(m_ampVelocity, Virus::Param_AmpVelocity); + _parameterBinding.bind(m_panoramaVelocity, Virus::Param_PanoramaVelocity); + _parameterBinding.bind(m_osc2ShapeVelocity, Virus::Param_Osc2ShapeVelocity); + _parameterBinding.bind(m_fmAmountVelocity, Virus::Param_FmAmountVelocity); + + // Filters + for (auto *s : {&m_cutoff1, &m_res1, &m_envAmount1, &m_keyTrack1, &m_resVel1, &m_envVel1, &m_cutoff2, &m_res2, + &m_envAmount2, &m_keyTrack2, &m_resVel2, &m_envVel2, &m_filterBalance}) + { + setupRotary(*this, *s); + } + + m_cutoff1.setBounds(1474 - knobSize / 2, 102 - knobSize / 2, knobSize, knobSize); + m_res1.setBounds(1618 - knobSize / 2, 102 - knobSize / 2, knobSize, knobSize); + m_envAmount1.setBounds(1762 - knobSize / 2, 102 - knobSize / 2, knobSize, knobSize); + m_keyTrack1.setBounds(1909 - knobSize / 2, 102 - knobSize / 2, knobSize, knobSize); + m_resVel1.setBounds(2053 - knobSize / 2, 102 - knobSize / 2, knobSize, knobSize); + m_envVel1.setBounds(2193 - knobSize / 2, 102 - knobSize / 2, knobSize, knobSize); + m_cutoff2.setBounds(1474 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); + m_res2.setBounds(1618 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); + m_envAmount2.setBounds(1762 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); + m_keyTrack2.setBounds(1909 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); + m_resVel2.setBounds(2053 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); + m_envVel2.setBounds(2193 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); + m_filterBalance.setBounds(1522 - knobSize / 2, 302 - knobSize / 2, knobSize, knobSize); + + m_filterMode1.setBounds(1710 + comboBoxXMargin - comboBox3Width / 2, 239 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + m_filterMode2.setBounds(1710 + comboBoxXMargin - comboBox3Width / 2, 353 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + m_filterRouting.setBounds(2017 + comboBoxXMargin - comboBox3Width / 2, 242 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + m_saturationCurve.setBounds(2017 + comboBoxXMargin - comboBox3Width / 2, 353 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + m_keyFollowBase.setBounds(1876 + comboBoxXMargin - comboBox2Width / 2, 303 - comboBox2Height / 2, + comboBox2Width, comboBox2Height); + + addAndMakeVisible(m_filterMode1); + addAndMakeVisible(m_filterMode2); + addAndMakeVisible(m_filterRouting); + addAndMakeVisible(m_saturationCurve); + addAndMakeVisible(m_keyFollowBase); + + m_envPol1.setBounds(2166 - m_envPol1.kWidth / 2, 241 - m_envPol1.kHeight / 2, m_envPol1.kWidth, + m_envPol1.kHeight); + m_envPol2.setBounds(2166 - m_envPol2.kWidth / 2, 351 - m_envPol2.kHeight / 2, m_envPol2.kWidth, + m_envPol2.kHeight); + m_link1.setBounds(1401 - m_link1.kWidth / 2, 302 - m_link1.kHeight / 2, m_link1.kWidth, m_link1.kHeight); + m_link2.setBounds(2266 - m_link2.kWidth / 2, 302 - m_link2.kHeight / 2, m_link2.kWidth, m_link2.kHeight); + + addAndMakeVisible(m_envPol1); + addAndMakeVisible(m_envPol2); + addAndMakeVisible(m_link1); + addAndMakeVisible(m_link2); + + _parameterBinding.bind(m_cutoff1, Virus::Param_FilterCutA); + _parameterBinding.bind(m_res1, Virus::Param_FilterResA); + _parameterBinding.bind(m_envAmount1, Virus::Param_FilterEnvAmtA); + _parameterBinding.bind(m_keyTrack1, Virus::Param_FilterKeyFollowA); + _parameterBinding.bind(m_resVel1, Virus::Param_Resonance1Velocity); + _parameterBinding.bind(m_envVel1, Virus::Param_Filter1EnvAmtVelocity); + _parameterBinding.bind(m_cutoff2, Virus::Param_FilterCutB); + _parameterBinding.bind(m_res2, Virus::Param_FilterResB); + _parameterBinding.bind(m_envAmount2, Virus::Param_FilterEnvAmtB); + _parameterBinding.bind(m_keyTrack2, Virus::Param_FilterKeyFollowB); + _parameterBinding.bind(m_resVel2, Virus::Param_Resonance2Velocity); + _parameterBinding.bind(m_envVel2, Virus::Param_Filter2EnvAmtVelocity); + _parameterBinding.bind(m_filterBalance, Virus::Param_FilterBalance); + + _parameterBinding.bind(m_filterMode1, Virus::Param_FilterModeA); + _parameterBinding.bind(m_filterMode2, Virus::Param_FilterModeB); + _parameterBinding.bind(m_filterRouting, Virus::Param_FilterRouting); + _parameterBinding.bind(m_saturationCurve, Virus::Param_SaturationCurve); + _parameterBinding.bind(m_keyFollowBase, Virus::Param_FilterKeytrackBase); + + _parameterBinding.bind(m_envPol1, Virus::Param_Filter1EnvPolarity); + _parameterBinding.bind(m_envPol2, Virus::Param_Filter2EnvPolarity); + _parameterBinding.bind(m_link1, Virus::Param_Filter2CutoffLink); + // todo no parameter for link2! + //_parameterBinding.bind(m_link2, Virus::Param_Filter ); + + // Env filter + for (auto *s : {&m_fltAttack, &m_fltDecay, &m_fltSustain, &m_fltTime, &m_fltRelease}) + { + setupRotary(*this, *s); + } + + m_fltAttack.setBounds(1474 - knobSize / 2, 695 - knobSize / 2, knobSize, knobSize); + m_fltDecay.setBounds(1648 - knobSize / 2, 695 - knobSize / 2, knobSize, knobSize); + m_fltSustain.setBounds(1830 - knobSize / 2, 695 - knobSize / 2, knobSize, knobSize); + m_fltTime.setBounds(2016 - knobSize / 2, 695 - knobSize / 2, knobSize, knobSize); + m_fltRelease.setBounds(2193 - knobSize / 2, 695 - knobSize / 2, knobSize, knobSize); + + _parameterBinding.bind(m_fltAttack, Virus::Param_FilterEnvAttack); + _parameterBinding.bind(m_fltDecay, Virus::Param_FilterEnvDecay); + _parameterBinding.bind(m_fltSustain, Virus::Param_FilterEnvSustain); + _parameterBinding.bind(m_fltTime, Virus::Param_FilterEnvSustainTime); + _parameterBinding.bind(m_fltRelease, Virus::Param_FilterEnvRelease); + + // Env Amp + for (auto *s : {&m_ampAttack, &m_ampDecay, &m_ampSustain, &m_ampTime, &m_ampRelease}) + { + setupRotary(*this, *s); + } + + m_ampAttack.setBounds(1474 - knobSize / 2, 904 - knobSize / 2, knobSize, knobSize); + m_ampDecay.setBounds(1648 - knobSize / 2, 904 - knobSize / 2, knobSize, knobSize); + m_ampSustain.setBounds(1830 - knobSize / 2, 904 - knobSize / 2, knobSize, knobSize); + m_ampTime.setBounds(2016 - knobSize / 2, 904 - knobSize / 2, knobSize, knobSize); + m_ampRelease.setBounds(2193 - knobSize / 2, 904 - knobSize / 2, knobSize, knobSize); + + _parameterBinding.bind(m_ampAttack, Virus::Param_AmpEnvAttack); + _parameterBinding.bind(m_ampDecay, Virus::Param_AmpEnvDecay); + _parameterBinding.bind(m_ampSustain, Virus::Param_AmpEnvSustain); + _parameterBinding.bind(m_ampTime, Virus::Param_AmpEnvSustainTime); + _parameterBinding.bind(m_ampRelease, Virus::Param_AmpEnvRelease); } - m_detune.setBounds(287 - knobSize / 2, 903 - knobSize / 2, knobSize, knobSize); - m_panSpread.setBounds(434 - knobSize / 2, 903 - knobSize / 2, knobSize, knobSize); - m_lfoPhase.setBounds(577 - knobSize / 2, 903 - knobSize / 2, knobSize, knobSize); - addAndMakeVisible(m_unisonVoices); - m_unisonVoices.setBounds(114+comboBoxXMargin - comboBoxWidth / 2, 903 - comboBoxHeight / 2, comboBoxWidth, comboBoxHeight); - - _parameterBinding.bind(m_detune, Virus::Param_UnisonDetune); - _parameterBinding.bind(m_panSpread, Virus::Param_UnisonPanSpread); - _parameterBinding.bind(m_lfoPhase, Virus::Param_UnisonLfoPhase); - _parameterBinding.bind(m_unisonVoices, Virus::Param_UnisonMode); - - // Punch - setupRotary(*this, m_Punch); - m_Punch.setBounds(841 - knobSize / 2, 903 - knobSize / 2, knobSize, knobSize); - _parameterBinding.bind(m_Punch, Virus::Param_PunchIntensity); - - // Mixer - for (auto *s : {&m_oscBalance, &m_oscLevel, &m_osc3Level, &m_oscSublevel, &m_noiseLevel, &m_ringModLevel}) - { - setupRotary(*this, *s); - } - - m_oscBalance.setBounds(1260 - knobSize / 2, 102 - knobSize / 2, knobSize, knobSize); - m_oscLevel.setBounds(1260 - knobSize / 2, 263 - knobSize / 2, knobSize, knobSize); - m_osc3Level.setBounds(1260 - knobSize / 2, 422 - knobSize / 2, knobSize, knobSize); - m_oscSublevel.setBounds(1260 - knobSize / 2, 579 - knobSize / 2, knobSize, knobSize); - m_noiseLevel.setBounds(1260 - knobSize / 2, 744 - knobSize / 2, knobSize, knobSize); - m_ringModLevel.setBounds(1260 - knobSize / 2, 903 - knobSize / 2, knobSize, knobSize); - - _parameterBinding.bind(m_oscBalance, Virus::Param_OscBalance); - _parameterBinding.bind(m_oscLevel, Virus::Param_OscMainVolume); - _parameterBinding.bind(m_osc3Level, Virus::Param_Osc3Volume); - _parameterBinding.bind(m_oscSublevel, Virus::Param_SubOscVolume); - _parameterBinding.bind(m_noiseLevel, Virus::Param_NoiseVolume); - _parameterBinding.bind(m_ringModLevel, Virus::Param_RingModMVolume); - - //Velo mod - for (auto *s : {&m_osc1ShapeVelocity, &m_pulseWidthVelocity, &m_ampVelocity, &m_panoramaVelocity, &m_osc2ShapeVelocity, &m_fmAmountVelocity}) - { - setupRotary(*this, *s); - } - - m_osc1ShapeVelocity.setBounds(1067 - knobSize / 2, 102 - knobSize / 2, knobSize, knobSize); - m_osc2ShapeVelocity.setBounds(1067 - knobSize / 2, 264 - knobSize / 2, knobSize, knobSize); - m_pulseWidthVelocity.setBounds(1067 - knobSize / 2, 421 - knobSize / 2, knobSize, knobSize); - m_fmAmountVelocity.setBounds(1067 - knobSize / 2, 579 - knobSize / 2, knobSize, knobSize); - m_ampVelocity.setBounds(1067 - knobSize / 2, 743 - knobSize / 2, knobSize, knobSize); - m_panoramaVelocity.setBounds(1067 - knobSize / 2, 903 - knobSize / 2, knobSize, knobSize); - - _parameterBinding.bind(m_osc1ShapeVelocity, Virus::Param_Osc1ShapeVelocity); - _parameterBinding.bind(m_pulseWidthVelocity, Virus::Param_PulseWidthVelocity); - _parameterBinding.bind(m_ampVelocity, Virus::Param_AmpVelocity); - _parameterBinding.bind(m_panoramaVelocity, Virus::Param_PanoramaVelocity); - _parameterBinding.bind(m_osc2ShapeVelocity, Virus::Param_Osc2ShapeVelocity); - _parameterBinding.bind(m_fmAmountVelocity, Virus::Param_FmAmountVelocity); - - //Filters - for (auto *s : {&m_cutoff1, &m_res1, &m_envAmount1, &m_keyTrack1, &m_resVel1, &m_envVel1, &m_cutoff2, &m_res2, &m_envAmount2, &m_keyTrack2, &m_resVel2, &m_envVel2, &m_filterBalance}) - { - setupRotary(*this, *s); - } - - m_cutoff1.setBounds(1474 - knobSize / 2, 102 - knobSize / 2, knobSize, knobSize); - m_res1.setBounds(1618 - knobSize / 2, 102 - knobSize / 2, knobSize, knobSize); - m_envAmount1.setBounds(1762 - knobSize / 2, 102 - knobSize / 2, knobSize, knobSize); - m_keyTrack1.setBounds(1909 - knobSize / 2, 102 - knobSize / 2, knobSize, knobSize); - m_resVel1.setBounds(2053 - knobSize / 2, 102 - knobSize / 2, knobSize, knobSize); - m_envVel1.setBounds(2193 - knobSize / 2, 102 - knobSize / 2, knobSize, knobSize); - m_cutoff2.setBounds(1474 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); - m_res2.setBounds(1618 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); - m_envAmount2.setBounds(1762 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); - m_keyTrack2.setBounds(1909 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); - m_resVel2.setBounds(2053 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); - m_envVel2.setBounds(2193 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); - m_filterBalance.setBounds(1522 - knobSize / 2, 302 - knobSize / 2, knobSize, knobSize); - - m_filterMode1.setBounds(1710+comboBoxXMargin - comboBox3Width / 2, 239 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - m_filterMode2.setBounds(1710+comboBoxXMargin - comboBox3Width / 2, 353 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - m_filterRouting.setBounds(2017+comboBoxXMargin - comboBox3Width / 2, 242 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - m_saturationCurve.setBounds(2017+comboBoxXMargin - comboBox3Width / 2, 353 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - m_keyFollowBase.setBounds(1876+comboBoxXMargin - comboBox2Width / 2, 303 - comboBox2Height / 2, comboBox2Width, comboBox2Height); - - addAndMakeVisible(m_filterMode1); - addAndMakeVisible(m_filterMode2); - addAndMakeVisible(m_filterRouting); - addAndMakeVisible(m_saturationCurve); - addAndMakeVisible(m_keyFollowBase); - - m_envPol1.setBounds(2166 - m_envPol1.kWidth / 2, 241 - m_envPol1.kHeight / 2, m_envPol1.kWidth, m_envPol1.kHeight); - m_envPol2.setBounds(2166 - m_envPol2.kWidth / 2, 351 - m_envPol2.kHeight / 2, m_envPol2.kWidth, m_envPol2.kHeight); - m_link1.setBounds(1401 - m_link1.kWidth / 2, 302 - m_link1.kHeight / 2, m_link1.kWidth, m_link1.kHeight); - m_link2.setBounds(2266 - m_link2.kWidth / 2, 302 - m_link2.kHeight / 2, m_link2.kWidth, m_link2.kHeight); - - addAndMakeVisible(m_envPol1); - addAndMakeVisible(m_envPol2); - addAndMakeVisible(m_link1); - addAndMakeVisible(m_link2); - - _parameterBinding.bind(m_cutoff1, Virus::Param_FilterCutA); - _parameterBinding.bind(m_res1, Virus::Param_FilterResA); - _parameterBinding.bind(m_envAmount1, Virus::Param_FilterEnvAmtA); - _parameterBinding.bind(m_keyTrack1, Virus::Param_FilterKeyFollowA); - _parameterBinding.bind(m_resVel1, Virus::Param_Resonance1Velocity); - _parameterBinding.bind(m_envVel1, Virus::Param_Filter1EnvAmtVelocity); - _parameterBinding.bind(m_cutoff2, Virus::Param_FilterCutB); - _parameterBinding.bind(m_res2, Virus::Param_FilterResB); - _parameterBinding.bind(m_envAmount2, Virus::Param_FilterEnvAmtB); - _parameterBinding.bind(m_keyTrack2, Virus::Param_FilterKeyFollowB); - _parameterBinding.bind(m_resVel2, Virus::Param_Resonance2Velocity); - _parameterBinding.bind(m_envVel2, Virus::Param_Filter2EnvAmtVelocity); - _parameterBinding.bind(m_filterBalance, Virus::Param_FilterBalance); - - _parameterBinding.bind(m_filterMode1, Virus::Param_FilterModeA); - _parameterBinding.bind(m_filterMode2, Virus::Param_FilterModeB); - _parameterBinding.bind(m_filterRouting, Virus::Param_FilterRouting); - _parameterBinding.bind(m_saturationCurve, Virus::Param_SaturationCurve); - _parameterBinding.bind(m_keyFollowBase, Virus::Param_FilterKeytrackBase); - - _parameterBinding.bind(m_envPol1, Virus::Param_Filter1EnvPolarity); - _parameterBinding.bind(m_envPol2, Virus::Param_Filter2EnvPolarity); - _parameterBinding.bind(m_link1, Virus::Param_Filter2CutoffLink); - //todo no parameter for link2! - //_parameterBinding.bind(m_link2, Virus::Param_Filter ); - - //Env filter - for (auto *s : {&m_fltAttack, &m_fltDecay, &m_fltSustain, &m_fltTime, &m_fltRelease}) - { - setupRotary(*this, *s); - } - - m_fltAttack.setBounds(1474 - knobSize / 2, 695 - knobSize / 2, knobSize, knobSize); - m_fltDecay.setBounds(1648 - knobSize / 2, 695 - knobSize / 2, knobSize, knobSize); - m_fltSustain.setBounds(1830 - knobSize / 2, 695 - knobSize / 2, knobSize, knobSize); - m_fltTime.setBounds(2016 - knobSize / 2, 695 - knobSize / 2, knobSize, knobSize); - m_fltRelease.setBounds(2193 - knobSize / 2, 695 - knobSize / 2, knobSize, knobSize); - - _parameterBinding.bind(m_fltAttack, Virus::Param_FilterEnvAttack); - _parameterBinding.bind(m_fltDecay, Virus::Param_FilterEnvDecay); - _parameterBinding.bind(m_fltSustain, Virus::Param_FilterEnvSustain); - _parameterBinding.bind(m_fltTime, Virus::Param_FilterEnvSustainTime); - _parameterBinding.bind(m_fltRelease, Virus::Param_FilterEnvRelease); - - //Env Amp - for (auto *s : {&m_ampAttack, &m_ampDecay, &m_ampSustain, &m_ampTime, &m_ampRelease}) - { - setupRotary(*this, *s); - } - - m_ampAttack.setBounds(1474 - knobSize / 2, 904 - knobSize / 2, knobSize, knobSize); - m_ampDecay.setBounds(1648 - knobSize / 2, 904 - knobSize / 2, knobSize, knobSize); - m_ampSustain.setBounds(1830 - knobSize / 2, 904 - knobSize / 2, knobSize, knobSize); - m_ampTime.setBounds(2016 - knobSize / 2, 904 - knobSize / 2, knobSize, knobSize); - m_ampRelease.setBounds(2193 - knobSize / 2, 904 - knobSize / 2, knobSize, knobSize); - - _parameterBinding.bind(m_ampAttack, Virus::Param_AmpEnvAttack); - _parameterBinding.bind(m_ampDecay, Virus::Param_AmpEnvDecay); - _parameterBinding.bind(m_ampSustain, Virus::Param_AmpEnvSustain); - _parameterBinding.bind(m_ampTime, Virus::Param_AmpEnvSustainTime); - _parameterBinding.bind(m_ampRelease, Virus::Param_AmpEnvRelease); -} - -void OscEditor::resized() -{ -} -\ No newline at end of file + void OscEditor::resized() {} +} // namespace Trancy +\ No newline at end of file diff --git a/source/jucePlugin/ui2/Virus_Panel1_OscEditor.h b/source/jucePlugin/ui2/Virus_Panel1_OscEditor.h @@ -2,65 +2,68 @@ #include "../PluginProcessor.h" #include "Virus_Buttons.h" - class VirusParameterBinding; - -class OscEditor : public juce::Component +namespace Trancy { -public: - OscEditor(VirusParameterBinding& _parameterBinding); - void resized() override; -private: - - // OSC1 - juce::Slider m_osc1Shape, m_osc1PulseWidth, m_osc1Semitone, m_osc1KeyFollow; - juce::ComboBox m_osc1WaveSelect; + class OscEditor : public juce::Component + { + public: + OscEditor(VirusParameterBinding &_parameterBinding); + void resized() override; + + private: + // OSC1 + juce::Slider m_osc1Shape, m_osc1PulseWidth, m_osc1Semitone, m_osc1KeyFollow; + juce::ComboBox m_osc1WaveSelect; + + // OSC2 + juce::Slider m_osc2Shape, m_osc2PulseWidth, m_osc2Semitone, m_osc2KeyFollow; + juce::ComboBox m_osc2WaveSelect; + + juce::Slider m_osc2FmAmount, m_osc2Detune, m_osc2EnvFm, m_osc2envOSC, m_osc2PhaseInit; + juce::ComboBox m_osc2FmMode; - // OSC2 - juce::Slider m_osc2Shape,m_osc2PulseWidth,m_osc2Semitone,m_osc2KeyFollow; - juce::ComboBox m_osc2WaveSelect; + Buttons::Button3 m_syncOsc1Osc2; - juce::Slider m_osc2FmAmount, m_osc2Detune, m_osc2EnvFm, m_osc2envOSC, m_osc2PhaseInit; - juce::ComboBox m_osc2FmMode; - - Buttons::Button3 m_syncOsc1Osc2; + // OSC3 + juce::Slider m_osc3Semitone, m_osc3Detune; + juce::ComboBox m_osc3Mode; - // OSC3 - juce::Slider m_osc3Semitone,m_osc3Detune; - juce::ComboBox m_osc3Mode; + // OSC Sub + Buttons::Button2 m_subWaveform; + juce::Slider m_noiseColor; - // OSC Sub - Buttons::Button2 m_subWaveform; - juce::Slider m_noiseColor; + // Unison + juce::Slider m_detune, m_panSpread, m_lfoPhase; + juce::ComboBox m_unisonVoices; - // Unison - juce::Slider m_detune, m_panSpread,m_lfoPhase; - juce::ComboBox m_unisonVoices; + // Punch + juce::Slider m_Punch; - // Punch - juce::Slider m_Punch; + // Mixer : juce::Component + juce::Slider m_oscBalance, m_oscLevel, m_osc3Level, m_oscSublevel, m_noiseLevel, m_ringModLevel; - // Mixer : juce::Component - juce::Slider m_oscBalance,m_oscLevel,m_osc3Level, m_oscSublevel, m_noiseLevel,m_ringModLevel; + // Vel + juce::Slider m_osc1ShapeVelocity, m_pulseWidthVelocity, m_ampVelocity, m_panoramaVelocity, m_osc2ShapeVelocity, + m_fmAmountVelocity; - // Vel - juce::Slider m_osc1ShapeVelocity,m_pulseWidthVelocity,m_ampVelocity, m_panoramaVelocity,m_osc2ShapeVelocity,m_fmAmountVelocity; + // Filters + juce::Slider m_cutoff1, m_res1, m_envAmount1, m_keyTrack1, m_resVel1, m_envVel1; + juce::Slider m_cutoff2, m_res2, m_envAmount2, m_keyTrack2, m_resVel2, m_envVel2; + juce::Slider m_filterBalance; - // Filters - juce::Slider m_cutoff1,m_res1, m_envAmount1,m_keyTrack1,m_resVel1,m_envVel1; - juce::Slider m_cutoff2,m_res2, m_envAmount2, m_keyTrack2,m_resVel2,m_envVel2; - juce::Slider m_filterBalance; + Buttons::Button2 m_envPol1, m_envPol2; + Buttons::Button1 m_link1, m_link2; + juce::ComboBox m_filterMode1, m_filterMode2, m_filterRouting, m_saturationCurve, m_keyFollowBase; - Buttons::Button2 m_envPol1, m_envPol2; - Buttons::Button1 m_link1, m_link2; - juce::ComboBox m_filterMode1, m_filterMode2, m_filterRouting, m_saturationCurve, m_keyFollowBase; + // Filter Envelope + juce::Slider m_fltAttack, m_fltDecay, m_fltSustain, m_fltTime, m_fltRelease; - // Filter Envelope - juce::Slider m_fltAttack,m_fltDecay, m_fltSustain,m_fltTime,m_fltRelease; + // Amp Envelope + juce::Slider m_ampAttack, m_ampDecay, m_ampSustain, m_ampTime, m_ampRelease; - // Amp Envelope - juce::Slider m_ampAttack,m_ampDecay,m_ampSustain,m_ampTime,m_ampRelease; + std::unique_ptr<juce::Drawable> m_background; + }; - std::unique_ptr<juce::Drawable> m_background; -}; +} // namespace Trancy +\ No newline at end of file diff --git a/source/jucePlugin/ui2/Virus_Panel2_LfoEditor.cpp b/source/jucePlugin/ui2/Virus_Panel2_LfoEditor.cpp @@ -2,244 +2,289 @@ #include "BinaryData.h" #include "Ui_Utils.h" #include "../VirusParameterBinding.h" - -using namespace juce; - - -LfoEditor::LfoEditor(VirusParameterBinding& _parameterBinding) +class VirusParameterBinding; +namespace Trancy { - setupBackground(*this, m_background, BinaryData::panel_2_png, BinaryData::panel_2_pngSize); - setBounds(m_background->getDrawableBounds().toNearestIntEdges()); - - //LFO 1 - for (auto *s : {&m_lfo1Rate, &m_lfo1Symmetry, &m_lfo1Osc1Pitch, &m_lfo1Osc2Pitch, &m_lfo1Pw12, &m_lfo1Reso12, - &m_lfo1KeyFollow, &m_lfo1Keytrigger, &m_lfo1AssignAmount, &m_lfo1FilterGain}) - { - setupRotary(*this, *s); - } - - m_lfo1Rate.setBounds(102 - knobSize / 2, 125 - knobSize / 2, knobSize, knobSize); - m_lfo1Symmetry.setBounds(417 - knobSize / 2, 125 - knobSize / 2, knobSize, knobSize); - m_lfo1Osc1Pitch.setBounds(102 - knobSize / 2, 313 - knobSize / 2, knobSize, knobSize); - m_lfo1Osc2Pitch.setBounds(262 - knobSize / 2, 313 - knobSize / 2, knobSize, knobSize); - m_lfo1Pw12.setBounds(417 - knobSize / 2, 313 - knobSize / 2, knobSize, knobSize); - m_lfo1Reso12.setBounds(102 - knobSize / 2, 517 - knobSize / 2, knobSize, knobSize); - m_lfo1KeyFollow.setBounds(258 - knobSize / 2, 517 - knobSize / 2, knobSize, knobSize); - m_lfo1Keytrigger.setBounds(417 - knobSize / 2, 517 - knobSize / 2, knobSize, knobSize); - m_lfo1AssignAmount.setBounds(102 - knobSize / 2, 705 - knobSize / 2, knobSize, knobSize); - m_lfo1FilterGain.setBounds(417 - knobSize / 2, 886 - knobSize / 2, knobSize, knobSize); - - addAndMakeVisible(m_lfo1Clock); - m_lfo1Clock.setBounds(258+comboBoxXMargin - comboBoxWidth / 2, 84 - comboBoxHeight / 2, comboBoxWidth, comboBoxHeight); - addAndMakeVisible(m_lfo1Shape); - m_lfo1Shape.setBounds(258+comboBoxXMargin - comboBoxWidth / 2, 169 - comboBoxHeight / 2, comboBoxWidth, comboBoxHeight); - addAndMakeVisible(m_lfo1AssignDest); - m_lfo1AssignDest.setBounds(283+comboBoxXMargin - comboBox3Width / 2, 700 - comboBoxHeight / 2, comboBox3Width, comboBoxHeight); - - addAndMakeVisible(m_lfo1Link); - m_lfo1Link.setBounds(177 - m_lfo1Link.kWidth / 2, 416 - m_lfo1Link.kHeight / 2, m_lfo1Link.kWidth, m_lfo1Link.kHeight); - addAndMakeVisible(m_lfo1LfoMode); - m_lfo1LfoMode.setBounds(102 - m_lfo1LfoMode.kWidth / 2, 879 - m_lfo1LfoMode.kHeight / 2, m_lfo1LfoMode.kWidth, m_lfo1LfoMode.kHeight); - addAndMakeVisible(m_lfo1EnvMode); - m_lfo1EnvMode.setBounds(442 - m_lfo1EnvMode.kWidth / 2, 701 - m_lfo1EnvMode.kHeight / 2, m_lfo1EnvMode.kWidth, m_lfo1EnvMode.kHeight); - - _parameterBinding.bind(m_lfo1Rate, Virus::Param_Lfo1Rate); - _parameterBinding.bind(m_lfo1Symmetry, Virus::Param_Lfo1Symmetry); - _parameterBinding.bind(m_lfo1Osc1Pitch, Virus::Param_Osc1Lfo1Amount); - _parameterBinding.bind(m_lfo1Osc2Pitch, Virus::Param_Osc2Lfo1Amount); - _parameterBinding.bind(m_lfo1Pw12, Virus::Param_PWLfo1Amount); - _parameterBinding.bind(m_lfo1Reso12, Virus::Param_ResoLfo1Amount); - _parameterBinding.bind(m_lfo1KeyFollow, Virus::Param_Lfo1Keyfollow); - _parameterBinding.bind(m_lfo1Keytrigger, Virus::Param_Lfo1KeyTrigger); - _parameterBinding.bind(m_lfo1AssignAmount, Virus::Param_Lfo1AssignAmount); - _parameterBinding.bind(m_lfo1FilterGain, Virus::Param_FltGainLfo1Amount); - - _parameterBinding.bind(m_lfo1Clock, Virus::Param_Lfo1Clock); - _parameterBinding.bind(m_lfo1Shape, Virus::Param_Lfo1Shape); - _parameterBinding.bind(m_lfo1AssignDest, Virus::Param_Lfo1AssignDest); - - //todo no link! _parameterBinding.bind(m_lfo1Link, Virus::lfo); - _parameterBinding.bind(m_lfo1LfoMode, Virus::Param_Lfo1Mode); - _parameterBinding.bind(m_lfo1EnvMode, Virus::Param_Lfo1EnvMode); - - // LFO 2 - for (auto *s : {&m_lfo2Rate, &m_lfo2Symmetry, &m_lfo2Filter1Cutoff, &m_lfo2Filter2Cutoff, &m_lfo2Shape12, - &m_lfo2Panorama, &m_lfo2KeyFollow, &m_lfo2Keytrigger, &m_lfo2AssignAmount, &m_lfo2AmtFM}) - { - setupRotary(*this, *s); - } - - m_lfo2Rate.setBounds(102 + 532 - knobSize / 2, 125 - knobSize / 2, knobSize, knobSize); - m_lfo2Symmetry.setBounds(417 + 532 - knobSize / 2, 125 - knobSize / 2, knobSize, knobSize); - m_lfo2Filter1Cutoff.setBounds(102 + 532 - knobSize / 2, 313 - knobSize / 2, knobSize, knobSize); - m_lfo2Filter2Cutoff.setBounds(262 + 532 - knobSize / 2, 313 - knobSize / 2, knobSize, knobSize); - m_lfo2Shape12.setBounds(417 + 532 - knobSize / 2, 313 - knobSize / 2, knobSize, knobSize); - m_lfo2Panorama.setBounds(102 + 532 - knobSize / 2, 517 - knobSize / 2, knobSize, knobSize); - m_lfo2KeyFollow.setBounds(258 + 532 - knobSize / 2, 517 - knobSize / 2, knobSize, knobSize); - m_lfo2Keytrigger.setBounds(417 + 532 - knobSize / 2, 517 - knobSize / 2, knobSize, knobSize); - m_lfo2AssignAmount.setBounds(102 + 532 - knobSize / 2, 705 - knobSize / 2, knobSize, knobSize); - m_lfo2AmtFM.setBounds(417 + 532 - knobSize / 2, 886 - knobSize / 2, knobSize, knobSize); - - addAndMakeVisible(m_lfo2Clock); - m_lfo2Clock.setBounds(258 + 532 + comboBoxXMargin - comboBoxWidth / 2, 84 - comboBoxHeight / 2, comboBoxWidth, comboBoxHeight); - addAndMakeVisible(m_lfo2Shape); - m_lfo2Shape.setBounds(258 + 532 +comboBoxXMargin - comboBoxWidth / 2, 169 - comboBoxHeight / 2, comboBoxWidth, comboBoxHeight); - addAndMakeVisible(m_lfo2AssignDest); - m_lfo2AssignDest.setBounds(283 + 532 +comboBoxXMargin - comboBox3Width / 2, 700 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - - addAndMakeVisible(m_lfo2Link); - m_lfo2Link.setBounds(177 + 532 - m_lfo2Link.kWidth / 2, 416 - m_lfo2Link.kHeight / 2, m_lfo2Link.kWidth, m_lfo2Link.kHeight); - addAndMakeVisible(m_lfo2LfoMode); - m_lfo2LfoMode.setBounds(102 + 532 - m_lfo2LfoMode.kWidth / 2, 879 - m_lfo2LfoMode.kHeight / 2, m_lfo2LfoMode.kWidth, m_lfo2LfoMode.kHeight); - addAndMakeVisible(m_lfo2EnvMode); - m_lfo2EnvMode.setBounds(442 + 532 - m_lfo2EnvMode.kWidth / 2, 701 - m_lfo2EnvMode.kHeight / 2, m_lfo2EnvMode.kWidth, m_lfo2EnvMode.kHeight); - - _parameterBinding.bind(m_lfo2Rate, Virus::Param_Lfo2Rate); - _parameterBinding.bind(m_lfo2Symmetry, Virus::Param_Lfo2Symmetry); - _parameterBinding.bind(m_lfo2Filter1Cutoff, Virus::Param_Cutoff1Lfo2Amount); - _parameterBinding.bind(m_lfo2Filter2Cutoff, Virus::Param_Cutoff2Lfo2Amount); - _parameterBinding.bind(m_lfo2Shape12, Virus::Param_OscShapeLfo2Amount); - _parameterBinding.bind(m_lfo2Panorama, Virus::Param_PanoramaLfo2Amount); - _parameterBinding.bind(m_lfo2KeyFollow, Virus::Param_Lfo2Keyfollow); - _parameterBinding.bind(m_lfo2Keytrigger, Virus::Param_Lfo2Keytrigger); - _parameterBinding.bind(m_lfo2AssignAmount, Virus::Param_Lfo2AssignAmount); - _parameterBinding.bind(m_lfo2AmtFM, Virus::Param_FmAmountLfo2Amount); - - _parameterBinding.bind(m_lfo2Clock, Virus::Param_Lfo2Clock); - _parameterBinding.bind(m_lfo2Shape, Virus::Param_Lfo2Shape); - _parameterBinding.bind(m_lfo2AssignDest, Virus::Param_Lfo2AssignDest); - - // todo no link! _parameterBinding.bind(m_lfo2Link, Virus::lfo); - _parameterBinding.bind(m_lfo2LfoMode, Virus::Param_Lfo2Mode); - _parameterBinding.bind(m_lfo2EnvMode, Virus::Param_Lfo2EnvMode); - - - // LFO 3 - for (auto *s : {&m_lfo3Rate, &m_lfo3FadeIn, &m_lfo3KeyFollow, &m_lfo3AssignAmount,}) - { - setupRotary(*this, *s); - } - - m_lfo3Rate.setBounds(1166 - knobSize / 2, 125 - knobSize / 2, knobSize, knobSize); - m_lfo3FadeIn.setBounds(1166 - knobSize / 2, 313 - knobSize / 2, knobSize, knobSize); - m_lfo3KeyFollow.setBounds(1322 - knobSize / 2, 313 - knobSize / 2, knobSize, knobSize); - m_lfo3AssignAmount.setBounds(1166 - knobSize / 2, 517 - knobSize / 2, knobSize, knobSize); - - addAndMakeVisible(m_lfo3Clock); - m_lfo3Clock.setBounds(1322+comboBoxXMargin - comboBoxWidth / 2, 84 - comboBoxHeight / 2, comboBoxWidth, comboBoxHeight); - addAndMakeVisible(m_lfo3Shape); - m_lfo3Shape.setBounds(1322+comboBoxXMargin - comboBoxWidth / 2, 169 - comboBoxHeight / 2, comboBoxWidth, comboBoxHeight); - addAndMakeVisible(m_lfo3AssignDest); - m_lfo3AssignDest.setBounds(1211+comboBoxXMargin - comboBox3Width / 2, 675 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - - addAndMakeVisible(m_lfo3LfoMode); - m_lfo3LfoMode.setBounds(1305 - m_lfo3LfoMode.kWidth / 2, 509 - m_lfo3LfoMode.kHeight / 2, m_lfo3LfoMode.kWidth, m_lfo3LfoMode.kHeight); - - _parameterBinding.bind(m_lfo3Rate, Virus::Param_Lfo3Rate); - _parameterBinding.bind(m_lfo3FadeIn, Virus::Param_Lfo3FadeInTime); - _parameterBinding.bind(m_lfo3KeyFollow, Virus::Param_Lfo3Keyfollow); - _parameterBinding.bind(m_lfo3AssignAmount, Virus::Param_OscLfo3Amount); - - _parameterBinding.bind(m_lfo3Clock, Virus::Param_Lfo3Clock); - _parameterBinding.bind(m_lfo3Shape, Virus::Param_Lfo3Shape); - _parameterBinding.bind(m_lfo3AssignDest, Virus::Param_Lfo3Destination); + using namespace juce; - // todo no link! _parameterBinding.bind(m_lfo3Link, Virus::lfo); - _parameterBinding.bind(m_lfo3LfoMode, Virus::Param_Lfo3Mode); - //Matrix Slo1 - for (auto *s : {&m_MatSlot1Amount1,&m_MatSlot1Amount2,&m_MatSlot1Amount3,&m_MatSlot1Amount4, - }) + LfoEditor::LfoEditor(VirusParameterBinding &_parameterBinding) { - setupRotary(*this, *s); + setupBackground(*this, m_background, BinaryData::panel_2_png, BinaryData::panel_2_pngSize); + setBounds(m_background->getDrawableBounds().toNearestIntEdges()); + + // LFO 1 + for (auto *s : {&m_lfo1Rate, &m_lfo1Symmetry, &m_lfo1Osc1Pitch, &m_lfo1Osc2Pitch, &m_lfo1Pw12, &m_lfo1Reso12, + &m_lfo1KeyFollow, &m_lfo1Keytrigger, &m_lfo1AssignAmount, &m_lfo1FilterGain}) + { + setupRotary(*this, *s); + } + + m_lfo1Rate.setBounds(102 - knobSize / 2, 125 - knobSize / 2, knobSize, knobSize); + m_lfo1Symmetry.setBounds(417 - knobSize / 2, 125 - knobSize / 2, knobSize, knobSize); + m_lfo1Osc1Pitch.setBounds(102 - knobSize / 2, 313 - knobSize / 2, knobSize, knobSize); + m_lfo1Osc2Pitch.setBounds(262 - knobSize / 2, 313 - knobSize / 2, knobSize, knobSize); + m_lfo1Pw12.setBounds(417 - knobSize / 2, 313 - knobSize / 2, knobSize, knobSize); + m_lfo1Reso12.setBounds(102 - knobSize / 2, 517 - knobSize / 2, knobSize, knobSize); + m_lfo1KeyFollow.setBounds(258 - knobSize / 2, 517 - knobSize / 2, knobSize, knobSize); + m_lfo1Keytrigger.setBounds(417 - knobSize / 2, 517 - knobSize / 2, knobSize, knobSize); + m_lfo1AssignAmount.setBounds(102 - knobSize / 2, 705 - knobSize / 2, knobSize, knobSize); + m_lfo1FilterGain.setBounds(417 - knobSize / 2, 886 - knobSize / 2, knobSize, knobSize); + + addAndMakeVisible(m_lfo1Clock); + m_lfo1Clock.setBounds(258 + comboBoxXMargin - comboBoxWidth / 2, 84 - comboBoxHeight / 2, comboBoxWidth, + comboBoxHeight); + addAndMakeVisible(m_lfo1Shape); + m_lfo1Shape.setBounds(258 + comboBoxXMargin - comboBoxWidth / 2, 169 - comboBoxHeight / 2, comboBoxWidth, + comboBoxHeight); + addAndMakeVisible(m_lfo1AssignDest); + m_lfo1AssignDest.setBounds(283 + comboBoxXMargin - comboBox3Width / 2, 700 - comboBoxHeight / 2, comboBox3Width, + comboBoxHeight); + + addAndMakeVisible(m_lfo1Link); + m_lfo1Link.setBounds(177 - m_lfo1Link.kWidth / 2, 416 - m_lfo1Link.kHeight / 2, m_lfo1Link.kWidth, + m_lfo1Link.kHeight); + addAndMakeVisible(m_lfo1LfoMode); + m_lfo1LfoMode.setBounds(102 - m_lfo1LfoMode.kWidth / 2, 879 - m_lfo1LfoMode.kHeight / 2, m_lfo1LfoMode.kWidth, + m_lfo1LfoMode.kHeight); + addAndMakeVisible(m_lfo1EnvMode); + m_lfo1EnvMode.setBounds(442 - m_lfo1EnvMode.kWidth / 2, 701 - m_lfo1EnvMode.kHeight / 2, m_lfo1EnvMode.kWidth, + m_lfo1EnvMode.kHeight); + + _parameterBinding.bind(m_lfo1Rate, Virus::Param_Lfo1Rate); + _parameterBinding.bind(m_lfo1Symmetry, Virus::Param_Lfo1Symmetry); + _parameterBinding.bind(m_lfo1Osc1Pitch, Virus::Param_Osc1Lfo1Amount); + _parameterBinding.bind(m_lfo1Osc2Pitch, Virus::Param_Osc2Lfo1Amount); + _parameterBinding.bind(m_lfo1Pw12, Virus::Param_PWLfo1Amount); + _parameterBinding.bind(m_lfo1Reso12, Virus::Param_ResoLfo1Amount); + _parameterBinding.bind(m_lfo1KeyFollow, Virus::Param_Lfo1Keyfollow); + _parameterBinding.bind(m_lfo1Keytrigger, Virus::Param_Lfo1KeyTrigger); + _parameterBinding.bind(m_lfo1AssignAmount, Virus::Param_Lfo1AssignAmount); + _parameterBinding.bind(m_lfo1FilterGain, Virus::Param_FltGainLfo1Amount); + + _parameterBinding.bind(m_lfo1Clock, Virus::Param_Lfo1Clock); + _parameterBinding.bind(m_lfo1Shape, Virus::Param_Lfo1Shape); + _parameterBinding.bind(m_lfo1AssignDest, Virus::Param_Lfo1AssignDest); + + // todo no link! _parameterBinding.bind(m_lfo1Link, Virus::lfo); + _parameterBinding.bind(m_lfo1LfoMode, Virus::Param_Lfo1Mode); + _parameterBinding.bind(m_lfo1EnvMode, Virus::Param_Lfo1EnvMode); + + // LFO 2 + for (auto *s : {&m_lfo2Rate, &m_lfo2Symmetry, &m_lfo2Filter1Cutoff, &m_lfo2Filter2Cutoff, &m_lfo2Shape12, + &m_lfo2Panorama, &m_lfo2KeyFollow, &m_lfo2Keytrigger, &m_lfo2AssignAmount, &m_lfo2AmtFM}) + { + setupRotary(*this, *s); + } + + m_lfo2Rate.setBounds(102 + 532 - knobSize / 2, 125 - knobSize / 2, knobSize, knobSize); + m_lfo2Symmetry.setBounds(417 + 532 - knobSize / 2, 125 - knobSize / 2, knobSize, knobSize); + m_lfo2Filter1Cutoff.setBounds(102 + 532 - knobSize / 2, 313 - knobSize / 2, knobSize, knobSize); + m_lfo2Filter2Cutoff.setBounds(262 + 532 - knobSize / 2, 313 - knobSize / 2, knobSize, knobSize); + m_lfo2Shape12.setBounds(417 + 532 - knobSize / 2, 313 - knobSize / 2, knobSize, knobSize); + m_lfo2Panorama.setBounds(102 + 532 - knobSize / 2, 517 - knobSize / 2, knobSize, knobSize); + m_lfo2KeyFollow.setBounds(258 + 532 - knobSize / 2, 517 - knobSize / 2, knobSize, knobSize); + m_lfo2Keytrigger.setBounds(417 + 532 - knobSize / 2, 517 - knobSize / 2, knobSize, knobSize); + m_lfo2AssignAmount.setBounds(102 + 532 - knobSize / 2, 705 - knobSize / 2, knobSize, knobSize); + m_lfo2AmtFM.setBounds(417 + 532 - knobSize / 2, 886 - knobSize / 2, knobSize, knobSize); + + addAndMakeVisible(m_lfo2Clock); + m_lfo2Clock.setBounds(258 + 532 + comboBoxXMargin - comboBoxWidth / 2, 84 - comboBoxHeight / 2, comboBoxWidth, + comboBoxHeight); + addAndMakeVisible(m_lfo2Shape); + m_lfo2Shape.setBounds(258 + 532 + comboBoxXMargin - comboBoxWidth / 2, 169 - comboBoxHeight / 2, comboBoxWidth, + comboBoxHeight); + addAndMakeVisible(m_lfo2AssignDest); + m_lfo2AssignDest.setBounds(283 + 532 + comboBoxXMargin - comboBox3Width / 2, 700 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + + addAndMakeVisible(m_lfo2Link); + m_lfo2Link.setBounds(177 + 532 - m_lfo2Link.kWidth / 2, 416 - m_lfo2Link.kHeight / 2, m_lfo2Link.kWidth, + m_lfo2Link.kHeight); + addAndMakeVisible(m_lfo2LfoMode); + m_lfo2LfoMode.setBounds(102 + 532 - m_lfo2LfoMode.kWidth / 2, 879 - m_lfo2LfoMode.kHeight / 2, + m_lfo2LfoMode.kWidth, m_lfo2LfoMode.kHeight); + addAndMakeVisible(m_lfo2EnvMode); + m_lfo2EnvMode.setBounds(442 + 532 - m_lfo2EnvMode.kWidth / 2, 701 - m_lfo2EnvMode.kHeight / 2, + m_lfo2EnvMode.kWidth, m_lfo2EnvMode.kHeight); + + _parameterBinding.bind(m_lfo2Rate, Virus::Param_Lfo2Rate); + _parameterBinding.bind(m_lfo2Symmetry, Virus::Param_Lfo2Symmetry); + _parameterBinding.bind(m_lfo2Filter1Cutoff, Virus::Param_Cutoff1Lfo2Amount); + _parameterBinding.bind(m_lfo2Filter2Cutoff, Virus::Param_Cutoff2Lfo2Amount); + _parameterBinding.bind(m_lfo2Shape12, Virus::Param_OscShapeLfo2Amount); + _parameterBinding.bind(m_lfo2Panorama, Virus::Param_PanoramaLfo2Amount); + _parameterBinding.bind(m_lfo2KeyFollow, Virus::Param_Lfo2Keyfollow); + _parameterBinding.bind(m_lfo2Keytrigger, Virus::Param_Lfo2Keytrigger); + _parameterBinding.bind(m_lfo2AssignAmount, Virus::Param_Lfo2AssignAmount); + _parameterBinding.bind(m_lfo2AmtFM, Virus::Param_FmAmountLfo2Amount); + + _parameterBinding.bind(m_lfo2Clock, Virus::Param_Lfo2Clock); + _parameterBinding.bind(m_lfo2Shape, Virus::Param_Lfo2Shape); + _parameterBinding.bind(m_lfo2AssignDest, Virus::Param_Lfo2AssignDest); + + // todo no link! _parameterBinding.bind(m_lfo2Link, Virus::lfo); + _parameterBinding.bind(m_lfo2LfoMode, Virus::Param_Lfo2Mode); + _parameterBinding.bind(m_lfo2EnvMode, Virus::Param_Lfo2EnvMode); + + + // LFO 3 + for (auto *s : { + &m_lfo3Rate, + &m_lfo3FadeIn, + &m_lfo3KeyFollow, + &m_lfo3AssignAmount, + }) + { + setupRotary(*this, *s); + } + + m_lfo3Rate.setBounds(1166 - knobSize / 2, 125 - knobSize / 2, knobSize, knobSize); + m_lfo3FadeIn.setBounds(1166 - knobSize / 2, 313 - knobSize / 2, knobSize, knobSize); + m_lfo3KeyFollow.setBounds(1322 - knobSize / 2, 313 - knobSize / 2, knobSize, knobSize); + m_lfo3AssignAmount.setBounds(1166 - knobSize / 2, 517 - knobSize / 2, knobSize, knobSize); + + addAndMakeVisible(m_lfo3Clock); + m_lfo3Clock.setBounds(1322 + comboBoxXMargin - comboBoxWidth / 2, 84 - comboBoxHeight / 2, comboBoxWidth, + comboBoxHeight); + addAndMakeVisible(m_lfo3Shape); + m_lfo3Shape.setBounds(1322 + comboBoxXMargin - comboBoxWidth / 2, 169 - comboBoxHeight / 2, comboBoxWidth, + comboBoxHeight); + addAndMakeVisible(m_lfo3AssignDest); + m_lfo3AssignDest.setBounds(1211 + comboBoxXMargin - comboBox3Width / 2, 675 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + + addAndMakeVisible(m_lfo3LfoMode); + m_lfo3LfoMode.setBounds(1305 - m_lfo3LfoMode.kWidth / 2, 509 - m_lfo3LfoMode.kHeight / 2, m_lfo3LfoMode.kWidth, + m_lfo3LfoMode.kHeight); + + _parameterBinding.bind(m_lfo3Rate, Virus::Param_Lfo3Rate); + _parameterBinding.bind(m_lfo3FadeIn, Virus::Param_Lfo3FadeInTime); + _parameterBinding.bind(m_lfo3KeyFollow, Virus::Param_Lfo3Keyfollow); + _parameterBinding.bind(m_lfo3AssignAmount, Virus::Param_OscLfo3Amount); + + _parameterBinding.bind(m_lfo3Clock, Virus::Param_Lfo3Clock); + _parameterBinding.bind(m_lfo3Shape, Virus::Param_Lfo3Shape); + _parameterBinding.bind(m_lfo3AssignDest, Virus::Param_Lfo3Destination); + + // todo no link! _parameterBinding.bind(m_lfo3Link, Virus::lfo); + _parameterBinding.bind(m_lfo3LfoMode, Virus::Param_Lfo3Mode); + + // Matrix Slo1 + for (auto *s : { + &m_MatSlot1Amount1, + &m_MatSlot1Amount2, + &m_MatSlot1Amount3, + &m_MatSlot1Amount4, + }) + { + setupRotary(*this, *s); + } + + m_MatSlot1Amount1.setBounds(1792 - knobSize / 2, 125 - knobSize / 2, knobSize, knobSize); + m_MatSlot1Amount2.setBounds(2197 - knobSize / 2, 125 - knobSize / 2, knobSize, knobSize); + m_MatSlot1Amount3.setBounds(1792 - knobSize / 2, 355 - knobSize / 2, knobSize, knobSize); + m_MatSlot1Amount4.setBounds(2197 - knobSize / 2, 355 - knobSize / 2, knobSize, knobSize); + + addAndMakeVisible(m_MatSlot1Source1); + m_MatSlot1Source1.setBounds(1597 + comboBoxXMargin - comboBox3Width / 2, 82 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + addAndMakeVisible(m_MatSlot1Source2); + m_MatSlot1Source2.setBounds(2002 + comboBoxXMargin - comboBox3Width / 2, 82 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + addAndMakeVisible(m_MatSlot1Source3); + m_MatSlot1Source3.setBounds(1597 + comboBoxXMargin - comboBox3Width / 2, 313 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + addAndMakeVisible(m_MatSlot1Source4); + m_MatSlot1Source4.setBounds(2002 + comboBoxXMargin - comboBox3Width / 2, 313 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + addAndMakeVisible(m_MatSlot1AssignDest1); + m_MatSlot1AssignDest1.setBounds(1597 + comboBoxXMargin - comboBox3Width / 2, 171 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + addAndMakeVisible(m_MatSlot1AssignDest2); + m_MatSlot1AssignDest2.setBounds(2002 + comboBoxXMargin - comboBox3Width / 2, 171 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + addAndMakeVisible(m_MatSlot1AssignDest3); + m_MatSlot1AssignDest3.setBounds(1597 + comboBoxXMargin - comboBox3Width / 2, 400 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + addAndMakeVisible(m_MatSlot1AssignDest4); + m_MatSlot1AssignDest4.setBounds(2002 + comboBoxXMargin - comboBox3Width / 2, 400 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + + _parameterBinding.bind(m_MatSlot1Source1, Virus::Param_Assign1Source); + _parameterBinding.bind(m_MatSlot1Source2, Virus::Param_Assign4Source); + _parameterBinding.bind(m_MatSlot1Source3, Virus::Param_Assign5Source); + _parameterBinding.bind(m_MatSlot1Source4, Virus::Param_Assign6Source); + _parameterBinding.bind(m_MatSlot1Amount1, Virus::Param_Assign1Amount); + _parameterBinding.bind(m_MatSlot1Amount2, Virus::Param_Assign4Amount); + _parameterBinding.bind(m_MatSlot1Amount3, Virus::Param_Assign5Amount); + _parameterBinding.bind(m_MatSlot1Amount4, Virus::Param_Assign6Amount); + _parameterBinding.bind(m_MatSlot1AssignDest1, Virus::Param_Assign1Destination); + _parameterBinding.bind(m_MatSlot1AssignDest2, Virus::Param_Assign4Destination); + _parameterBinding.bind(m_MatSlot1AssignDest3, Virus::Param_Assign5Destination); + _parameterBinding.bind(m_MatSlot1AssignDest4, Virus::Param_Assign6Destination); + + // Matrix Slot 2 + for (auto *s : {&m_MatSlot2Amount1, &m_MatSlot2Amount2}) + { + setupRotary(*this, *s); + } + + m_MatSlot2Amount1.setBounds(1792 - knobSize / 2, 624 - knobSize / 2, knobSize, knobSize); + m_MatSlot2Amount2.setBounds(2197 - knobSize / 2, 624 - knobSize / 2, knobSize, knobSize); + addAndMakeVisible(m_MatSlot2Source12); + m_MatSlot2Source12.setBounds(1597 + comboBoxXMargin - comboBox3Width / 2, 576 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + addAndMakeVisible(m_MatSlot2AssignDest1); + m_MatSlot2AssignDest1.setBounds(1597 + comboBoxXMargin - comboBox3Width / 2, 666 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + addAndMakeVisible(m_MatSlot2AssignDest2); + m_MatSlot2AssignDest2.setBounds(2002 + comboBoxXMargin - comboBox3Width / 2, 624 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + + _parameterBinding.bind(m_MatSlot2Source12, Virus::Param_Assign2Source); + _parameterBinding.bind(m_MatSlot2Amount1, Virus::Param_Assign2Amount1); + _parameterBinding.bind(m_MatSlot2Amount2, Virus::Param_Assign2Amount2); + _parameterBinding.bind(m_MatSlot2AssignDest1, Virus::Param_Assign2Destination1); + _parameterBinding.bind(m_MatSlot2AssignDest2, Virus::Param_Assign2Destination2); + + + // Matrix Slot 3 + for (auto *s : {&m_MatSlot3Amount1, &m_MatSlot3Amount2, &m_MatSlot3Amount3}) + { + setupRotary(*this, *s); + } + + m_MatSlot3Amount1.setBounds(1404 - knobSize / 2, 886 - knobSize / 2, knobSize, knobSize); + m_MatSlot3Amount2.setBounds(1792 - knobSize / 2, 886 - knobSize / 2, knobSize, knobSize); + m_MatSlot3Amount3.setBounds(2197 - knobSize / 2, 886 - knobSize / 2, knobSize, knobSize); + + addAndMakeVisible(m_MatSlot3Source123); + m_MatSlot3Source123.setBounds(1210 + comboBoxXMargin - comboBox3Width / 2, 838 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + + addAndMakeVisible(m_MatSlot3AssignDest1); + m_MatSlot3AssignDest1.setBounds(1210 + comboBoxXMargin - comboBox3Width / 2, 928 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + + addAndMakeVisible(m_MatSlot3AssignDest2); + m_MatSlot3AssignDest2.setBounds(1596 + comboBoxXMargin - comboBox3Width / 2, 888 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + + addAndMakeVisible(m_MatSlot3AssignDest3); + m_MatSlot3AssignDest3.setBounds(2002 + comboBoxXMargin - comboBox3Width / 2, 888 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + + _parameterBinding.bind(m_MatSlot3Source123, Virus::Param_Assign3Source); + + _parameterBinding.bind(m_MatSlot3Amount1, Virus::Param_Assign3Amount1); + _parameterBinding.bind(m_MatSlot3Amount2, Virus::Param_Assign3Amount2); + _parameterBinding.bind(m_MatSlot3Amount3, + Virus::Param_Assign2Amount3); // todo: need fix typ --> Param_Assign3Amount3 + + _parameterBinding.bind(m_MatSlot3AssignDest1, Virus::Param_Assign3Destination1); + _parameterBinding.bind(m_MatSlot3AssignDest2, Virus::Param_Assign3Destination2); + _parameterBinding.bind(m_MatSlot3AssignDest3, + Virus::Param_Assign2Destination3); // todo: need fix typ --> Param_Assign3Destination3 } - - m_MatSlot1Amount1.setBounds(1792 - knobSize / 2, 125 - knobSize / 2, knobSize, knobSize); - m_MatSlot1Amount2.setBounds(2197 - knobSize / 2, 125 - knobSize / 2, knobSize, knobSize); - m_MatSlot1Amount3.setBounds(1792 - knobSize / 2, 355 - knobSize / 2, knobSize, knobSize); - m_MatSlot1Amount4.setBounds(2197 - knobSize / 2, 355 - knobSize / 2, knobSize, knobSize); - - addAndMakeVisible(m_MatSlot1Source1); - m_MatSlot1Source1.setBounds(1597+comboBoxXMargin - comboBox3Width / 2, 82 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - addAndMakeVisible(m_MatSlot1Source2); - m_MatSlot1Source2.setBounds(2002+comboBoxXMargin - comboBox3Width / 2, 82 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - addAndMakeVisible(m_MatSlot1Source3); - m_MatSlot1Source3.setBounds(1597+comboBoxXMargin - comboBox3Width / 2, 313 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - addAndMakeVisible(m_MatSlot1Source4); - m_MatSlot1Source4.setBounds(2002+comboBoxXMargin - comboBox3Width / 2, 313 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - addAndMakeVisible(m_MatSlot1AssignDest1); - m_MatSlot1AssignDest1.setBounds(1597+comboBoxXMargin - comboBox3Width / 2, 171 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - addAndMakeVisible(m_MatSlot1AssignDest2); - m_MatSlot1AssignDest2.setBounds(2002+comboBoxXMargin - comboBox3Width / 2, 171 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - addAndMakeVisible(m_MatSlot1AssignDest3); - m_MatSlot1AssignDest3.setBounds(1597+comboBoxXMargin- comboBox3Width / 2, 400 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - addAndMakeVisible(m_MatSlot1AssignDest4); - m_MatSlot1AssignDest4.setBounds(2002+comboBoxXMargin - comboBox3Width / 2, 400 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - - _parameterBinding.bind(m_MatSlot1Source1, Virus::Param_Assign1Source); - _parameterBinding.bind(m_MatSlot1Source2, Virus::Param_Assign4Source); - _parameterBinding.bind(m_MatSlot1Source3, Virus::Param_Assign5Source); - _parameterBinding.bind(m_MatSlot1Source4, Virus::Param_Assign6Source); - _parameterBinding.bind(m_MatSlot1Amount1, Virus::Param_Assign1Amount); - _parameterBinding.bind(m_MatSlot1Amount2, Virus::Param_Assign4Amount); - _parameterBinding.bind(m_MatSlot1Amount3, Virus::Param_Assign5Amount); - _parameterBinding.bind(m_MatSlot1Amount4, Virus::Param_Assign6Amount); - _parameterBinding.bind(m_MatSlot1AssignDest1, Virus::Param_Assign1Destination); - _parameterBinding.bind(m_MatSlot1AssignDest2, Virus::Param_Assign4Destination); - _parameterBinding.bind(m_MatSlot1AssignDest3, Virus::Param_Assign5Destination); - _parameterBinding.bind(m_MatSlot1AssignDest4, Virus::Param_Assign6Destination); - - // Matrix Slot 2 - for (auto *s : { &m_MatSlot2Amount1, &m_MatSlot2Amount2}) - { - setupRotary(*this, *s); - } - - m_MatSlot2Amount1.setBounds(1792 - knobSize / 2, 624 - knobSize / 2, knobSize, knobSize); - m_MatSlot2Amount2.setBounds(2197 - knobSize / 2, 624 - knobSize / 2, knobSize, knobSize); - addAndMakeVisible(m_MatSlot2Source12); - m_MatSlot2Source12.setBounds(1597+comboBoxXMargin - comboBox3Width / 2, 576 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - addAndMakeVisible(m_MatSlot2AssignDest1); - m_MatSlot2AssignDest1.setBounds(1597+comboBoxXMargin - comboBox3Width / 2, 666 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - addAndMakeVisible(m_MatSlot2AssignDest2); - m_MatSlot2AssignDest2.setBounds(2002+comboBoxXMargin - comboBox3Width / 2, 624 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - - _parameterBinding.bind(m_MatSlot2Source12, Virus::Param_Assign2Source); - _parameterBinding.bind(m_MatSlot2Amount1, Virus::Param_Assign2Amount1); - _parameterBinding.bind(m_MatSlot2Amount2, Virus::Param_Assign2Amount2); - _parameterBinding.bind(m_MatSlot2AssignDest1, Virus::Param_Assign2Destination1); - _parameterBinding.bind(m_MatSlot2AssignDest2, Virus::Param_Assign2Destination2); - - - // Matrix Slot 3 - for (auto *s : {&m_MatSlot3Amount1,&m_MatSlot3Amount2,&m_MatSlot3Amount3}) - { - setupRotary(*this, *s); - } - - m_MatSlot3Amount1.setBounds(1404 - knobSize / 2, 886 - knobSize / 2, knobSize, knobSize); - m_MatSlot3Amount2.setBounds(1792 - knobSize / 2, 886 - knobSize / 2, knobSize, knobSize); - m_MatSlot3Amount3.setBounds(2197 - knobSize / 2, 886 - knobSize / 2, knobSize, knobSize); - - addAndMakeVisible(m_MatSlot3Source123); - m_MatSlot3Source123.setBounds(1210+comboBoxXMargin - comboBox3Width / 2, 838 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - - addAndMakeVisible(m_MatSlot3AssignDest1); - m_MatSlot3AssignDest1.setBounds(1210+comboBoxXMargin - comboBox3Width / 2, 928 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - - addAndMakeVisible(m_MatSlot3AssignDest2); - m_MatSlot3AssignDest2.setBounds(1596+comboBoxXMargin - comboBox3Width / 2, 888 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - - addAndMakeVisible(m_MatSlot3AssignDest3); - m_MatSlot3AssignDest3.setBounds(2002+comboBoxXMargin - comboBox3Width / 2, 888 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - - _parameterBinding.bind(m_MatSlot3Source123, Virus::Param_Assign3Source); - - _parameterBinding.bind(m_MatSlot3Amount1, Virus::Param_Assign3Amount1); - _parameterBinding.bind(m_MatSlot3Amount2, Virus::Param_Assign3Amount2); - _parameterBinding.bind(m_MatSlot3Amount3, Virus::Param_Assign2Amount3); //todo: need fix typ --> Param_Assign3Amount3 - - _parameterBinding.bind(m_MatSlot3AssignDest1, Virus::Param_Assign3Destination1); - _parameterBinding.bind(m_MatSlot3AssignDest2, Virus::Param_Assign3Destination2); - _parameterBinding.bind(m_MatSlot3AssignDest3, Virus::Param_Assign2Destination3); //todo: need fix typ --> Param_Assign3Destination3 -} +} // namespace Trancy +\ No newline at end of file diff --git a/source/jucePlugin/ui2/Virus_Panel2_LfoEditor.h b/source/jucePlugin/ui2/Virus_Panel2_LfoEditor.h @@ -2,51 +2,52 @@ #include "../PluginProcessor.h" #include "Virus_Buttons.h" - - class VirusParameterBinding; - -class LfoEditor : public juce::Component +namespace Trancy { -public: - LfoEditor(VirusParameterBinding& _parameterBinding); - -private: - //LFO 1 - juce::Slider m_lfo1Rate, m_lfo1Symmetry, m_lfo1Osc1Pitch, m_lfo1Osc2Pitch, m_lfo1Pw12, m_lfo1Reso12, - m_lfo1KeyFollow, m_lfo1Keytrigger, m_lfo1AssignAmount, m_lfo1FilterGain; - juce::ComboBox m_lfo1Clock, m_lfo1Shape, m_lfo1AssignDest; - Buttons::Button4 m_lfo1Link; - Buttons::Button2 m_lfo1LfoMode; - Buttons::Button3 m_lfo1EnvMode; - - //LFO 2 - juce::Slider m_lfo2Rate, m_lfo2Symmetry, m_lfo2Filter1Cutoff, m_lfo2Filter2Cutoff, m_lfo2Shape12, m_lfo2Panorama, - m_lfo2KeyFollow, m_lfo2Keytrigger, m_lfo2AssignAmount, m_lfo2AmtFM; - juce::ComboBox m_lfo2Clock, m_lfo2Shape, m_lfo2AssignDest; - Buttons::Button4 m_lfo2Link; - Buttons::Button2 m_lfo2LfoMode; - Buttons::Button3 m_lfo2EnvMode; - - //LFO 3 - juce::Slider m_lfo3Rate, m_lfo3FadeIn, m_lfo3KeyFollow, m_lfo3AssignAmount; - juce::ComboBox m_lfo3Clock, m_lfo3Shape, m_lfo3AssignDest; - Buttons::Button2 m_lfo3LfoMode; - - //Matrix Slo1 - juce::Slider m_MatSlot1Amount1, m_MatSlot1Amount2, m_MatSlot1Amount3, m_MatSlot1Amount4; - juce::ComboBox m_MatSlot1Source1, m_MatSlot1Source2, m_MatSlot1Source3, m_MatSlot1Source4; - juce::ComboBox m_MatSlot1AssignDest1, m_MatSlot1AssignDest2, m_MatSlot1AssignDest3, m_MatSlot1AssignDest4; - - // Matrix Slo2 - juce::Slider m_MatSlot2Amount1, m_MatSlot2Amount2; - juce::ComboBox m_MatSlot2Source12; - juce::ComboBox m_MatSlot2AssignDest1, m_MatSlot2AssignDest2; - - // Matrix Slo3 - juce::Slider m_MatSlot3Amount1, m_MatSlot3Amount2, m_MatSlot3Amount3; - juce::ComboBox m_MatSlot3Source123; - juce::ComboBox m_MatSlot3AssignDest1, m_MatSlot3AssignDest2, m_MatSlot3AssignDest3; - - std::unique_ptr<juce::Drawable> m_background; -}; + class LfoEditor : public juce::Component + { + public: + LfoEditor(VirusParameterBinding &_parameterBinding); + + private: + // LFO 1 + juce::Slider m_lfo1Rate, m_lfo1Symmetry, m_lfo1Osc1Pitch, m_lfo1Osc2Pitch, m_lfo1Pw12, m_lfo1Reso12, + m_lfo1KeyFollow, m_lfo1Keytrigger, m_lfo1AssignAmount, m_lfo1FilterGain; + juce::ComboBox m_lfo1Clock, m_lfo1Shape, m_lfo1AssignDest; + Buttons::Button4 m_lfo1Link; + Buttons::Button2 m_lfo1LfoMode; + Buttons::Button3 m_lfo1EnvMode; + + // LFO 2 + juce::Slider m_lfo2Rate, m_lfo2Symmetry, m_lfo2Filter1Cutoff, m_lfo2Filter2Cutoff, m_lfo2Shape12, + m_lfo2Panorama, m_lfo2KeyFollow, m_lfo2Keytrigger, m_lfo2AssignAmount, m_lfo2AmtFM; + juce::ComboBox m_lfo2Clock, m_lfo2Shape, m_lfo2AssignDest; + Buttons::Button4 m_lfo2Link; + Buttons::Button2 m_lfo2LfoMode; + Buttons::Button3 m_lfo2EnvMode; + + // LFO 3 + juce::Slider m_lfo3Rate, m_lfo3FadeIn, m_lfo3KeyFollow, m_lfo3AssignAmount; + juce::ComboBox m_lfo3Clock, m_lfo3Shape, m_lfo3AssignDest; + Buttons::Button2 m_lfo3LfoMode; + + // Matrix Slo1 + juce::Slider m_MatSlot1Amount1, m_MatSlot1Amount2, m_MatSlot1Amount3, m_MatSlot1Amount4; + juce::ComboBox m_MatSlot1Source1, m_MatSlot1Source2, m_MatSlot1Source3, m_MatSlot1Source4; + juce::ComboBox m_MatSlot1AssignDest1, m_MatSlot1AssignDest2, m_MatSlot1AssignDest3, m_MatSlot1AssignDest4; + + // Matrix Slo2 + juce::Slider m_MatSlot2Amount1, m_MatSlot2Amount2; + juce::ComboBox m_MatSlot2Source12; + juce::ComboBox m_MatSlot2AssignDest1, m_MatSlot2AssignDest2; + + // Matrix Slo3 + juce::Slider m_MatSlot3Amount1, m_MatSlot3Amount2, m_MatSlot3Amount3; + juce::ComboBox m_MatSlot3Source123; + juce::ComboBox m_MatSlot3AssignDest1, m_MatSlot3AssignDest2, m_MatSlot3AssignDest3; + + std::unique_ptr<juce::Drawable> m_background; + }; + +} // namespace Trancy +\ No newline at end of file diff --git a/source/jucePlugin/ui2/Virus_Panel3_FxEditor.cpp b/source/jucePlugin/ui2/Virus_Panel3_FxEditor.cpp @@ -2,350 +2,364 @@ #include "BinaryData.h" #include "Ui_Utils.h" #include "../VirusParameterBinding.h" - -using namespace juce; - - -FxEditor::FxEditor(VirusParameterBinding &_parameterBinding, AudioPluginAudioProcessor &_processorRef): m_controller(_processorRef.getController()) +class VirusParameterBinding; +namespace Trancy { - setupBackground(*this, m_background, BinaryData::panel_3_png, BinaryData::panel_3_pngSize); - setBounds(m_background->getDrawableBounds().toNearestIntEdges()); - - // envFollow - for (auto *s : {&m_envFollowLevel, &m_envFollowAttack, &m_eEnvFollowRelease}) - { - setupRotary(*this, *s); - } - - m_envFollowLevel.setBounds(219 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); - m_envFollowAttack.setBounds(365 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); - m_eEnvFollowRelease.setBounds(508 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); - - addAndMakeVisible(m_envFollow); - m_envFollow.setBounds(86 - m_envFollow.kWidth / 2, 113 - m_envFollow.kHeight / 2, m_envFollow.kWidth, m_envFollow.kHeight); - _parameterBinding.bind(m_envFollow, Virus::Param_InputFollowMode); - _parameterBinding.bind(m_envFollowAttack, Virus::Param_FilterEnvAttack); - _parameterBinding.bind(m_eEnvFollowRelease, Virus::Param_FilterEnvDecay); - _parameterBinding.bind(m_envFollowLevel, Virus::Param_FilterEnvSustain); - - // Distortion - for (auto *s : {&m_distortionIntensity}) - { - setupRotary(*this, *s); - } - m_distortionIntensity.setBounds(905 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); - - addAndMakeVisible(m_distortionCurve); - m_distortionCurve.setBounds(741+comboBoxXMargin - comboBox3Width / 2, 113 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - - _parameterBinding.bind(m_distortionIntensity, Virus::Param_DistortionIntensity); - _parameterBinding.bind(m_distortionCurve, Virus::Param_DistortionCurve); - - // Chorus - for (auto *s : {&m_chorusRate, &m_chorusDepth, &m_chorusFeedback, &m_chorusMix, &m_chorusDelay}) - { - setupRotary(*this, *s); - } - m_chorusRate.setBounds(1299 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); - m_chorusDepth.setBounds(1440 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); - m_chorusFeedback.setBounds(1584 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); - m_chorusMix.setBounds(1722 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); - m_chorusDelay.setBounds(1861 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); - - addAndMakeVisible(m_choruslfoShape); - m_choruslfoShape.setBounds(1129+comboBoxXMargin - comboBox3Width / 2, 113 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - - _parameterBinding.bind(m_chorusRate, Virus::Param_ChorusRate); - _parameterBinding.bind(m_chorusDepth, Virus::Param_ChorusDepth); - _parameterBinding.bind(m_chorusFeedback, Virus::Param_ChorusFeedback); - _parameterBinding.bind(m_chorusMix, Virus::Param_ChorusMix); - _parameterBinding.bind(m_chorusDelay, Virus::Param_ChorusDelay); - _parameterBinding.bind(m_choruslfoShape, Virus::Param_ChorusLfoShape); - - // AnalogBoost - for (auto *s : {&m_analogBoostIntensity, &m_AnalogBoostTune}) - { - setupRotary(*this, *s); - } + using namespace juce; - m_analogBoostIntensity.setBounds(2060 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); - m_AnalogBoostTune.setBounds(2203 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); - _parameterBinding.bind(m_analogBoostIntensity, Virus::Param_BassIntensity); - _parameterBinding.bind(m_AnalogBoostTune, Virus::Param_BassTune); - - // Phaser - for (auto *s : {&m_phaserMix, &m_phaserSpread, &m_phaserRate, &m_phaserDepth, &m_phaserFreq, &m_phaserFeedback}) - { - setupRotary(*this, *s); - } - m_phaserMix.setBounds(283 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); - m_phaserSpread.setBounds(420 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); - m_phaserRate.setBounds(554 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); - m_phaserDepth.setBounds(691 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); - m_phaserFreq.setBounds(825 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); - m_phaserFeedback.setBounds(961 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); - - addAndMakeVisible(m_stages); - m_stages.setBounds(114+comboBoxXMargin - comboBox3Width / 2, 339 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - - _parameterBinding.bind(m_phaserMix, Virus::Param_PhaserMix); - _parameterBinding.bind(m_phaserSpread, Virus::Param_PhaserSpread); - _parameterBinding.bind(m_phaserRate, Virus::Param_PhaserRate); - _parameterBinding.bind(m_phaserDepth, Virus::Param_PhaserDepth); - _parameterBinding.bind(m_phaserFreq, Virus::Param_PhaserFreq); - _parameterBinding.bind(m_phaserFeedback, Virus::Param_PhaserFeedback); - _parameterBinding.bind(m_stages, Virus::Param_PhaserMode); - - // Equalizer - m_equalizerLowGgain, m_equalizerLowFreq, m_equalizerMidGain, m_equalizerMidFreq, m_equalizerMidQ, m_equalizerHighGgain, m_equalizerHighFreq; - - for (auto *s : {&m_equalizerLowGgain, &m_equalizerLowFreq, &m_equalizerMidGain, &m_equalizerMidFreq, &m_equalizerMidQ, - &m_equalizerHighGgain, &m_equalizerHighFreq}) - { - setupRotary(*this, *s); - } - m_equalizerLowGgain.setBounds(1164 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); - m_equalizerLowFreq.setBounds(1304 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); - m_equalizerMidGain.setBounds(1448 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); - m_equalizerMidFreq.setBounds(1588 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); - m_equalizerMidQ.setBounds(1737 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); - m_equalizerHighGgain.setBounds(1882 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); - m_equalizerHighFreq.setBounds(2021 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); - - _parameterBinding.bind(m_equalizerLowGgain, Virus::Param_LowEqGain); - _parameterBinding.bind(m_equalizerLowFreq, Virus::Param_LowEqFreq); - _parameterBinding.bind(m_equalizerMidGain, Virus::Param_MidEqGain); - _parameterBinding.bind(m_equalizerMidFreq, Virus::Param_MidEqFreq); - _parameterBinding.bind(m_equalizerMidQ, Virus::Param_MidEqQFactor); - _parameterBinding.bind(m_equalizerHighGgain, Virus::Param_HighEqGain); - _parameterBinding.bind(m_equalizerHighFreq, Virus::Param_HighEqFreq); - - // RingModInput - for (auto *s : {&m_ringModMix}) + FxEditor::FxEditor(VirusParameterBinding &_parameterBinding, AudioPluginAudioProcessor &_processorRef) : + m_controller(_processorRef.getController()) { - setupRotary(*this, *s); + setupBackground(*this, m_background, BinaryData::panel_3_png, BinaryData::panel_3_pngSize); + setBounds(m_background->getDrawableBounds().toNearestIntEdges()); + + // envFollow + for (auto *s : {&m_envFollowLevel, &m_envFollowAttack, &m_eEnvFollowRelease}) + { + setupRotary(*this, *s); + } + + m_envFollowLevel.setBounds(219 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); + m_envFollowAttack.setBounds(365 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); + m_eEnvFollowRelease.setBounds(508 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); + + addAndMakeVisible(m_envFollow); + m_envFollow.setBounds(86 - m_envFollow.kWidth / 2, 113 - m_envFollow.kHeight / 2, m_envFollow.kWidth, + m_envFollow.kHeight); + + _parameterBinding.bind(m_envFollow, Virus::Param_InputFollowMode); + _parameterBinding.bind(m_envFollowAttack, Virus::Param_FilterEnvAttack); + _parameterBinding.bind(m_eEnvFollowRelease, Virus::Param_FilterEnvDecay); + _parameterBinding.bind(m_envFollowLevel, Virus::Param_FilterEnvSustain); + + // Distortion + for (auto *s : {&m_distortionIntensity}) + { + setupRotary(*this, *s); + } + m_distortionIntensity.setBounds(905 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); + + addAndMakeVisible(m_distortionCurve); + m_distortionCurve.setBounds(741 + comboBoxXMargin - comboBox3Width / 2, 113 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + + _parameterBinding.bind(m_distortionIntensity, Virus::Param_DistortionIntensity); + _parameterBinding.bind(m_distortionCurve, Virus::Param_DistortionCurve); + + // Chorus + for (auto *s : {&m_chorusRate, &m_chorusDepth, &m_chorusFeedback, &m_chorusMix, &m_chorusDelay}) + { + setupRotary(*this, *s); + } + m_chorusRate.setBounds(1299 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); + m_chorusDepth.setBounds(1440 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); + m_chorusFeedback.setBounds(1584 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); + m_chorusMix.setBounds(1722 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); + m_chorusDelay.setBounds(1861 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); + + addAndMakeVisible(m_choruslfoShape); + m_choruslfoShape.setBounds(1129 + comboBoxXMargin - comboBox3Width / 2, 113 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + + _parameterBinding.bind(m_chorusRate, Virus::Param_ChorusRate); + _parameterBinding.bind(m_chorusDepth, Virus::Param_ChorusDepth); + _parameterBinding.bind(m_chorusFeedback, Virus::Param_ChorusFeedback); + _parameterBinding.bind(m_chorusMix, Virus::Param_ChorusMix); + _parameterBinding.bind(m_chorusDelay, Virus::Param_ChorusDelay); + _parameterBinding.bind(m_choruslfoShape, Virus::Param_ChorusLfoShape); + + // AnalogBoost + for (auto *s : {&m_analogBoostIntensity, &m_AnalogBoostTune}) + { + setupRotary(*this, *s); + } + + m_analogBoostIntensity.setBounds(2060 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); + m_AnalogBoostTune.setBounds(2203 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); + + _parameterBinding.bind(m_analogBoostIntensity, Virus::Param_BassIntensity); + _parameterBinding.bind(m_AnalogBoostTune, Virus::Param_BassTune); + + // Phaser + for (auto *s : {&m_phaserMix, &m_phaserSpread, &m_phaserRate, &m_phaserDepth, &m_phaserFreq, &m_phaserFeedback}) + { + setupRotary(*this, *s); + } + m_phaserMix.setBounds(283 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); + m_phaserSpread.setBounds(420 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); + m_phaserRate.setBounds(554 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); + m_phaserDepth.setBounds(691 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); + m_phaserFreq.setBounds(825 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); + m_phaserFeedback.setBounds(961 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); + + addAndMakeVisible(m_stages); + m_stages.setBounds(114 + comboBoxXMargin - comboBox3Width / 2, 339 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + + _parameterBinding.bind(m_phaserMix, Virus::Param_PhaserMix); + _parameterBinding.bind(m_phaserSpread, Virus::Param_PhaserSpread); + _parameterBinding.bind(m_phaserRate, Virus::Param_PhaserRate); + _parameterBinding.bind(m_phaserDepth, Virus::Param_PhaserDepth); + _parameterBinding.bind(m_phaserFreq, Virus::Param_PhaserFreq); + _parameterBinding.bind(m_phaserFeedback, Virus::Param_PhaserFeedback); + _parameterBinding.bind(m_stages, Virus::Param_PhaserMode); + + // Equalizer + m_equalizerLowGgain, m_equalizerLowFreq, m_equalizerMidGain, m_equalizerMidFreq, m_equalizerMidQ, + m_equalizerHighGgain, m_equalizerHighFreq; + + for (auto *s : {&m_equalizerLowGgain, &m_equalizerLowFreq, &m_equalizerMidGain, &m_equalizerMidFreq, + &m_equalizerMidQ, &m_equalizerHighGgain, &m_equalizerHighFreq}) + { + setupRotary(*this, *s); + } + m_equalizerLowGgain.setBounds(1164 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); + m_equalizerLowFreq.setBounds(1304 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); + m_equalizerMidGain.setBounds(1448 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); + m_equalizerMidFreq.setBounds(1588 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); + m_equalizerMidQ.setBounds(1737 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); + m_equalizerHighGgain.setBounds(1882 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); + m_equalizerHighFreq.setBounds(2021 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); + + _parameterBinding.bind(m_equalizerLowGgain, Virus::Param_LowEqGain); + _parameterBinding.bind(m_equalizerLowFreq, Virus::Param_LowEqFreq); + _parameterBinding.bind(m_equalizerMidGain, Virus::Param_MidEqGain); + _parameterBinding.bind(m_equalizerMidFreq, Virus::Param_MidEqFreq); + _parameterBinding.bind(m_equalizerMidQ, Virus::Param_MidEqQFactor); + _parameterBinding.bind(m_equalizerHighGgain, Virus::Param_HighEqGain); + _parameterBinding.bind(m_equalizerHighFreq, Virus::Param_HighEqFreq); + + // RingModInput + for (auto *s : {&m_ringModMix}) + { + setupRotary(*this, *s); + } + m_ringModMix.setBounds(2212 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); + + _parameterBinding.bind(m_ringModMix, Virus::Param_InputRingMod); + + // Delay/Reverb + // Show hide Reverb + for (auto *s : {&m_delayReverbSend}) + { + setupRotary(*this, *s); + } + m_delayReverbSend.setBounds(113 - knobSize / 2, 607 - knobSize / 2, knobSize, knobSize); + + addAndMakeVisible(m_delayReverbMode); + m_delayReverbMode.setBounds(113 + comboBoxXMargin - comboBox3Width / 2, 763 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + + _parameterBinding.bind(m_delayReverbSend, Virus::Param_EffectSend); + _parameterBinding.bind(m_delayReverbMode, Virus::Param_DelayReverbMode); + + auto p = m_controller.getParameter(Virus::Param_DelayReverbMode, 0); + if (p) + { + const auto val = (int)p->getValueObject().getValueSource().getValue(); + DelayReverb(); + + p->onValueChanged = nullptr; + p->onValueChanged = [this, p]() { DelayReverb(); }; + } + + // Reverb selected + // Reverb + for (auto *s : {&m_reverbDecayTime, &m_reverbDaming, &m_reverbColoration, &m_reverbPredelay, &m_reverbFeedback}) + { + setupRotary(*this, *s); + } + + m_reverbDecayTime.setBounds(297 - knobSize / 2, 854 - knobSize / 2, knobSize, knobSize); + m_reverbDaming.setBounds(632 - knobSize / 2, 854 - knobSize / 2, knobSize, knobSize); + m_reverbColoration.setBounds(771 - knobSize / 2, 854 - knobSize / 2, knobSize, knobSize); + m_reverbPredelay.setBounds(909 - knobSize / 2, 854 - knobSize / 2, knobSize, knobSize); + m_reverbFeedback.setBounds(1052 - knobSize / 2, 854 - knobSize / 2, knobSize, knobSize); + + addAndMakeVisible(m_reverbType); + m_reverbType.setBounds(467 + comboBoxXMargin - comboBox3Width / 2, 854 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + + _parameterBinding.bind(m_reverbDecayTime, Virus::Param_DelayRateReverbDecayTime); + _parameterBinding.bind(m_reverbDaming, Virus::Param_DelayLfoShape); + _parameterBinding.bind(m_reverbColoration, Virus::Param_DelayColor); + _parameterBinding.bind(m_reverbPredelay, Virus::Param_DelayTime); + _parameterBinding.bind(m_reverbFeedback, Virus::Param_DelayFeedback); + _parameterBinding.bind(m_reverbType, Virus::Param_DelayDepthReverbRoomSize); + + // todo Need to check these parameters bindings for delay and reverb + // Delay + for (auto *s : {&m_delayTime, &m_delayRate, &m_delayFeedback, &m_delayColoration, &m_delayDepth}) + { + setupRotary(*this, *s); + } + m_delayTime.setBounds(297 - knobSize / 2, 607 - knobSize / 2, knobSize, knobSize); + m_delayRate.setBounds(632 - knobSize / 2, 607 - knobSize / 2, knobSize, knobSize); + m_delayFeedback.setBounds(771 - knobSize / 2, 607 - knobSize / 2, knobSize, knobSize); + m_delayColoration.setBounds(909 - knobSize / 2, 607 - knobSize / 2, knobSize, knobSize); + m_delayDepth.setBounds(1052 - knobSize / 2, 607 - knobSize / 2, knobSize, knobSize); + + addAndMakeVisible(m_delayClock); + m_delayClock.setBounds(467 + comboBoxXMargin - comboBox3Width / 2, 555 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + + addAndMakeVisible(m_delayShape); + m_delayShape.setBounds(467 + comboBoxXMargin - comboBox3Width / 2, 653 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + + _parameterBinding.bind(m_delayTime, Virus::Param_DelayTime); + _parameterBinding.bind(m_delayRate, Virus::Param_DelayRateReverbDecayTime); + _parameterBinding.bind(m_delayFeedback, Virus::Param_DelayFeedback); + _parameterBinding.bind(m_delayColoration, Virus::Param_DelayColor); + _parameterBinding.bind(m_delayDepth, Virus::Param_DelayDepthReverbRoomSize); + _parameterBinding.bind(m_delayClock, Virus::Param_DelayClock); + _parameterBinding.bind(m_delayShape, Virus::Param_DelayLfoShape); + + // Vocoder + for (auto *s : {&m_vocoderCenterFreq, &m_vocoderModOffset, &m_vocoderModQ, &m_vocoderModSpread, &m_vocoderCarrQ, + &m_vocoderCarrSpread, &m_vocoderSpectralBal, &m_vocoderBands, &m_vocoderAttack, + &m_vocoderRelease, &m_vocoderSourceBal}) + { + setupRotary(*this, *s); + } + + m_vocoderCenterFreq.setBounds(1487 - knobSize / 2, 625 - knobSize / 2, knobSize, knobSize); + m_vocoderModOffset.setBounds(1625 - knobSize / 2, 625 - knobSize / 2, knobSize, knobSize); + m_vocoderModQ.setBounds(1768 - knobSize / 2, 625 - knobSize / 2, knobSize, knobSize); + m_vocoderModSpread.setBounds(1912 - knobSize / 2, 625 - knobSize / 2, knobSize, knobSize); + m_vocoderCarrQ.setBounds(2055 - knobSize / 2, 625 - knobSize / 2, knobSize, knobSize); + m_vocoderCarrSpread.setBounds(2198 - knobSize / 2, 625 - knobSize / 2, knobSize, knobSize); + + m_vocoderSpectralBal.setBounds(1487 - knobSize / 2, 836 - knobSize / 2, knobSize, knobSize); + m_vocoderBands.setBounds(1625 - knobSize / 2, 836 - knobSize / 2, knobSize, knobSize); + m_vocoderAttack.setBounds(1768 - knobSize / 2, 836 - knobSize / 2, knobSize, knobSize); + m_vocoderRelease.setBounds(1912 - knobSize / 2, 836 - knobSize / 2, knobSize, knobSize); + m_vocoderSourceBal.setBounds(2055 - knobSize / 2, 836 - knobSize / 2, knobSize, knobSize); + + addAndMakeVisible(m_vocoderMode); + m_vocoderMode.setBounds(1273 + comboBoxXMargin - comboBox3Width / 2, 672 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + + addAndMakeVisible(m_vocoderModInput); + m_vocoderModInput.setBounds(1273 + comboBoxXMargin - comboBox3Width / 2, 787 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + + m_vocoderLink.setBounds(1987 - m_vocoderLink.kWidth / 2, 526 - m_vocoderLink.kHeight / 2, m_vocoderLink.kWidth, + m_vocoderLink.kHeight); + addAndMakeVisible(m_vocoderLink); + + // todo Need to check these parameters bindings + _parameterBinding.bind(m_vocoderCenterFreq, Virus::Param_FilterCutA); + _parameterBinding.bind(m_vocoderModOffset, Virus::Param_FilterCutB); + _parameterBinding.bind(m_vocoderModQ, Virus::Param_FilterResA); + _parameterBinding.bind(m_vocoderModSpread, Virus::Param_FilterKeyFollowA); + _parameterBinding.bind(m_vocoderCarrQ, Virus::Param_FilterResB); + _parameterBinding.bind(m_vocoderCarrSpread, Virus::Param_FilterKeyFollowB); + _parameterBinding.bind(m_vocoderSpectralBal, Virus::Param_FilterEnvSustainTime); + + _parameterBinding.bind(m_vocoderBands, Virus::Param_FilterEnvRelease); + _parameterBinding.bind(m_vocoderAttack, Virus::Param_FilterEnvAttack); + _parameterBinding.bind(m_vocoderRelease, Virus::Param_FilterEnvDecay); + _parameterBinding.bind(m_vocoderSourceBal, Virus::Param_FilterBalance); + + _parameterBinding.bind(m_vocoderMode, Virus::Param_VocoderMode); + _parameterBinding.bind(m_vocoderModInput, Virus::Param_InputSelect); + _parameterBinding.bind(m_vocoderLink, Virus::Param_Filter2CutoffLink); + + auto p1 = m_controller.getParameter(Virus::Param_VocoderMode, 0); + if (p1) + { + const auto val = (int)p1->getValueObject().getValueSource().getValue(); + Vocoder(); + + p1->onValueChanged = nullptr; + p1->onValueChanged = [this, p1]() { Vocoder(); }; + } } - m_ringModMix.setBounds(2212 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); - - _parameterBinding.bind(m_ringModMix, Virus::Param_InputRingMod); - // Delay/Reverb - //Show hide Reverb - for (auto *s : {&m_delayReverbSend}) + void FxEditor::Vocoder() { - setupRotary(*this, *s); - } - m_delayReverbSend.setBounds(113 - knobSize / 2, 607 - knobSize / 2, knobSize, knobSize); - - addAndMakeVisible(m_delayReverbMode); - m_delayReverbMode.setBounds(113+comboBoxXMargin - comboBox3Width / 2, 763 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - - _parameterBinding.bind(m_delayReverbSend, Virus::Param_EffectSend); - _parameterBinding.bind(m_delayReverbMode, Virus::Param_DelayReverbMode); - - auto p = m_controller.getParameter(Virus::Param_DelayReverbMode, 0); - if (p) { - const auto val = (int)p->getValueObject().getValueSource().getValue(); - DelayReverb(); - - p->onValueChanged = nullptr; - p->onValueChanged = [this, p]() { - DelayReverb(); - }; - } - - //Reverb selected - // Reverb - for (auto *s : {&m_reverbDecayTime, &m_reverbDaming, &m_reverbColoration, &m_reverbPredelay, &m_reverbFeedback}) - { - setupRotary(*this, *s); + // Vocoder + // m_vocoderMode + auto p = m_controller.getParameter(Virus::Param_VocoderMode, 0); + const auto value = (int)p->getValueObject().getValueSource().getValue(); + m_vocoderMode.setSelectedId(value + 1, dontSendNotification); + + int iSelectedIndex = m_vocoderMode.getSelectedItemIndex(); + bool bVocoder = (iSelectedIndex > 0); + float fAlpha = (bVocoder) ? 1.0f : 0.3f; + + m_vocoderCenterFreq.setEnabled(bVocoder); + m_vocoderCenterFreq.setAlpha(fAlpha); + m_vocoderModOffset.setEnabled(bVocoder); + m_vocoderModOffset.setAlpha(fAlpha); + m_vocoderModQ.setEnabled(bVocoder); + m_vocoderModQ.setAlpha(fAlpha); + m_vocoderModSpread.setEnabled(bVocoder); + m_vocoderModSpread.setAlpha(fAlpha); + m_vocoderCarrQ.setEnabled(bVocoder); + m_vocoderCarrQ.setAlpha(fAlpha); + m_vocoderCarrSpread.setEnabled(bVocoder); + m_vocoderCarrSpread.setAlpha(fAlpha); + m_vocoderSpectralBal.setEnabled(bVocoder); + m_vocoderSpectralBal.setAlpha(fAlpha); + m_vocoderBands.setEnabled(bVocoder); + m_vocoderBands.setAlpha(fAlpha); + m_vocoderAttack.setEnabled(bVocoder); + m_vocoderAttack.setAlpha(fAlpha); + m_vocoderRelease.setEnabled(bVocoder); + m_vocoderRelease.setAlpha(fAlpha); + m_vocoderSourceBal.setEnabled(bVocoder); + m_vocoderSourceBal.setAlpha(fAlpha); + // m_vocoderMode.setVisible(bVocoder); + m_vocoderModInput.setEnabled(bVocoder); + m_vocoderModInput.setAlpha(fAlpha); + m_vocoderLink.setEnabled(bVocoder); + m_vocoderLink.setAlpha(fAlpha); } - m_reverbDecayTime.setBounds(297 - knobSize / 2, 854 - knobSize / 2, knobSize, knobSize); - m_reverbDaming.setBounds(632 - knobSize / 2, 854 - knobSize / 2, knobSize, knobSize); - m_reverbColoration.setBounds(771 - knobSize / 2, 854 - knobSize / 2, knobSize, knobSize); - m_reverbPredelay.setBounds(909 - knobSize / 2, 854 - knobSize / 2, knobSize, knobSize); - m_reverbFeedback.setBounds(1052 - knobSize / 2, 854 - knobSize / 2, knobSize, knobSize); - - addAndMakeVisible(m_reverbType); - m_reverbType.setBounds(467+comboBoxXMargin - comboBox3Width / 2, 854 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - - _parameterBinding.bind(m_reverbDecayTime, Virus::Param_DelayRateReverbDecayTime); - _parameterBinding.bind(m_reverbDaming, Virus::Param_DelayLfoShape); - _parameterBinding.bind(m_reverbColoration, Virus::Param_DelayColor); - _parameterBinding.bind(m_reverbPredelay, Virus::Param_DelayTime); - _parameterBinding.bind(m_reverbFeedback, Virus::Param_DelayFeedback); - _parameterBinding.bind(m_reverbType, Virus::Param_DelayDepthReverbRoomSize); - - // todo Need to check these parameters bindings for delay and reverb - // Delay - for (auto *s : {&m_delayTime, &m_delayRate, &m_delayFeedback, &m_delayColoration, &m_delayDepth}) - { - setupRotary(*this, *s); - } - m_delayTime.setBounds(297 - knobSize / 2, 607 - knobSize / 2, knobSize, knobSize); - m_delayRate.setBounds(632 - knobSize / 2, 607 - knobSize / 2, knobSize, knobSize); - m_delayFeedback.setBounds(771 - knobSize / 2, 607 - knobSize / 2, knobSize, knobSize); - m_delayColoration.setBounds(909 - knobSize / 2, 607 - knobSize / 2, knobSize, knobSize); - m_delayDepth.setBounds(1052 - knobSize / 2, 607 - knobSize / 2, knobSize, knobSize); - - addAndMakeVisible(m_delayClock); - m_delayClock.setBounds(467+comboBoxXMargin - comboBox3Width / 2, 555 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - - addAndMakeVisible(m_delayShape); - m_delayShape.setBounds(467+comboBoxXMargin - comboBox3Width / 2, 653 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - - _parameterBinding.bind(m_delayTime, Virus::Param_DelayTime); - _parameterBinding.bind(m_delayRate, Virus::Param_DelayRateReverbDecayTime); - _parameterBinding.bind(m_delayFeedback, Virus::Param_DelayFeedback); - _parameterBinding.bind(m_delayColoration, Virus::Param_DelayColor); - _parameterBinding.bind(m_delayDepth, Virus::Param_DelayDepthReverbRoomSize); - _parameterBinding.bind(m_delayClock, Virus::Param_DelayClock); - _parameterBinding.bind(m_delayShape, Virus::Param_DelayLfoShape); - - // Vocoder - for (auto *s : {&m_vocoderCenterFreq, &m_vocoderModOffset, &m_vocoderModQ, &m_vocoderModSpread, &m_vocoderCarrQ, - &m_vocoderCarrSpread, &m_vocoderSpectralBal, &m_vocoderBands, &m_vocoderAttack, &m_vocoderRelease, - &m_vocoderSourceBal}) + void FxEditor::DelayReverb() { - setupRotary(*this, *s); + // rebind(); + auto p = m_controller.getParameter(Virus::Param_DelayReverbMode, 0); + const auto value = (int)p->getValueObject().getValueSource().getValue(); + m_delayReverbMode.setSelectedId(value + 1, dontSendNotification); + + // Delay/Reverb + int iSelectedIndex = m_delayReverbMode.getSelectedItemIndex(); + bool bReverb = (iSelectedIndex >= 2 && iSelectedIndex <= 4); + float fReverbAlpha = (bReverb) ? 1.0f : 0.3f; + bool bDelay = (iSelectedIndex == 1 || iSelectedIndex >= 5); + float fDelayAlpha = (bDelay) ? 1.0f : 0.3f; + + m_reverbDecayTime.setEnabled(bReverb); + m_reverbDecayTime.setAlpha(fReverbAlpha); + m_reverbDaming.setEnabled(bReverb); + m_reverbDaming.setAlpha(fReverbAlpha); + m_reverbColoration.setEnabled(bReverb); + m_reverbColoration.setAlpha(fReverbAlpha); + m_reverbPredelay.setEnabled(bReverb); + m_reverbPredelay.setAlpha(fReverbAlpha); + m_reverbFeedback.setEnabled(bReverb); + m_reverbFeedback.setAlpha(fReverbAlpha); + m_reverbType.setEnabled(bReverb); + m_reverbType.setAlpha(fReverbAlpha); + + m_delayTime.setEnabled(bDelay); + m_delayTime.setAlpha(fDelayAlpha); + m_delayRate.setEnabled(bDelay); + m_delayRate.setAlpha(fDelayAlpha); + m_delayFeedback.setEnabled(bDelay); + m_delayFeedback.setAlpha(fDelayAlpha); + m_delayColoration.setEnabled(bDelay); + m_delayColoration.setAlpha(fDelayAlpha); + m_delayDepth.setEnabled(bDelay); + m_delayDepth.setAlpha(fDelayAlpha); + m_delayClock.setEnabled(bDelay); + m_delayClock.setAlpha(fDelayAlpha); + m_delayShape.setEnabled(bDelay); + m_delayShape.setAlpha(fDelayAlpha); } - - m_vocoderCenterFreq.setBounds(1487 - knobSize / 2, 625 - knobSize / 2, knobSize, knobSize); - m_vocoderModOffset.setBounds(1625 - knobSize / 2, 625 - knobSize / 2, knobSize, knobSize); - m_vocoderModQ.setBounds(1768 - knobSize / 2, 625 - knobSize / 2, knobSize, knobSize); - m_vocoderModSpread.setBounds(1912 - knobSize / 2, 625 - knobSize / 2, knobSize, knobSize); - m_vocoderCarrQ.setBounds(2055 - knobSize / 2, 625 - knobSize / 2, knobSize, knobSize); - m_vocoderCarrSpread.setBounds(2198 - knobSize / 2, 625 - knobSize / 2, knobSize, knobSize); - - m_vocoderSpectralBal.setBounds(1487 - knobSize / 2, 836 - knobSize / 2, knobSize, knobSize); - m_vocoderBands.setBounds(1625 - knobSize / 2, 836 - knobSize / 2, knobSize, knobSize); - m_vocoderAttack.setBounds(1768 - knobSize / 2, 836 - knobSize / 2, knobSize, knobSize); - m_vocoderRelease.setBounds(1912 - knobSize / 2, 836 - knobSize / 2, knobSize, knobSize); - m_vocoderSourceBal.setBounds(2055 - knobSize / 2, 836 - knobSize / 2, knobSize, knobSize); - - addAndMakeVisible(m_vocoderMode); - m_vocoderMode.setBounds(1273+comboBoxXMargin - comboBox3Width / 2, 672 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - - addAndMakeVisible(m_vocoderModInput); - m_vocoderModInput.setBounds(1273+comboBoxXMargin - comboBox3Width / 2, 787 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - - m_vocoderLink.setBounds(1987 - m_vocoderLink.kWidth / 2, 526 - m_vocoderLink.kHeight / 2, m_vocoderLink.kWidth, m_vocoderLink.kHeight); - addAndMakeVisible(m_vocoderLink); - - //todo Need to check these parameters bindings - _parameterBinding.bind(m_vocoderCenterFreq, Virus::Param_FilterCutA); - _parameterBinding.bind(m_vocoderModOffset, Virus::Param_FilterCutB); - _parameterBinding.bind(m_vocoderModQ, Virus::Param_FilterResA); - _parameterBinding.bind(m_vocoderModSpread, Virus::Param_FilterKeyFollowA); - _parameterBinding.bind(m_vocoderCarrQ, Virus::Param_FilterResB); - _parameterBinding.bind(m_vocoderCarrSpread, Virus::Param_FilterKeyFollowB); - _parameterBinding.bind(m_vocoderSpectralBal, Virus::Param_FilterEnvSustainTime); - - _parameterBinding.bind(m_vocoderBands, Virus::Param_FilterEnvRelease); - _parameterBinding.bind(m_vocoderAttack, Virus::Param_FilterEnvAttack); - _parameterBinding.bind(m_vocoderRelease, Virus::Param_FilterEnvDecay); - _parameterBinding.bind(m_vocoderSourceBal, Virus::Param_FilterBalance); - - _parameterBinding.bind(m_vocoderMode, Virus::Param_VocoderMode); - _parameterBinding.bind(m_vocoderModInput, Virus::Param_InputSelect); - _parameterBinding.bind(m_vocoderLink, Virus::Param_Filter2CutoffLink); - - auto p1 = m_controller.getParameter(Virus::Param_VocoderMode, 0); - if (p1) { - const auto val = (int)p1->getValueObject().getValueSource().getValue(); - Vocoder(); - - p1->onValueChanged = nullptr; - p1->onValueChanged = [this, p1]() { - Vocoder(); - }; - } - -} - -void FxEditor::Vocoder() -{ - //Vocoder - //m_vocoderMode - auto p = m_controller.getParameter(Virus::Param_VocoderMode, 0); - const auto value = (int)p->getValueObject().getValueSource().getValue(); - m_vocoderMode.setSelectedId(value + 1, dontSendNotification); - - int iSelectedIndex = m_vocoderMode.getSelectedItemIndex(); - bool bVocoder = (iSelectedIndex > 0); - float fAlpha = (bVocoder)?1.0f:0.3f; - - m_vocoderCenterFreq.setEnabled(bVocoder); - m_vocoderCenterFreq.setAlpha(fAlpha); - m_vocoderModOffset.setEnabled(bVocoder); - m_vocoderModOffset.setAlpha(fAlpha); - m_vocoderModQ.setEnabled(bVocoder); - m_vocoderModQ.setAlpha(fAlpha); - m_vocoderModSpread.setEnabled(bVocoder); - m_vocoderModSpread.setAlpha(fAlpha); - m_vocoderCarrQ.setEnabled(bVocoder); - m_vocoderCarrQ.setAlpha(fAlpha); - m_vocoderCarrSpread.setEnabled(bVocoder); - m_vocoderCarrSpread.setAlpha(fAlpha); - m_vocoderSpectralBal.setEnabled(bVocoder); - m_vocoderSpectralBal.setAlpha(fAlpha); - m_vocoderBands.setEnabled(bVocoder); - m_vocoderBands.setAlpha(fAlpha); - m_vocoderAttack.setEnabled(bVocoder); - m_vocoderAttack.setAlpha(fAlpha); - m_vocoderRelease.setEnabled(bVocoder); - m_vocoderRelease.setAlpha(fAlpha); - m_vocoderSourceBal.setEnabled(bVocoder); - m_vocoderSourceBal.setAlpha(fAlpha); - //m_vocoderMode.setVisible(bVocoder); - m_vocoderModInput.setEnabled(bVocoder); - m_vocoderModInput.setAlpha(fAlpha); - m_vocoderLink.setEnabled(bVocoder); - m_vocoderLink.setAlpha(fAlpha); -} - -void FxEditor::DelayReverb() -{ - //rebind(); - auto p = m_controller.getParameter(Virus::Param_DelayReverbMode, 0); - const auto value = (int)p->getValueObject().getValueSource().getValue(); - m_delayReverbMode.setSelectedId(value + 1, dontSendNotification); - - //Delay/Reverb - int iSelectedIndex = m_delayReverbMode.getSelectedItemIndex(); - bool bReverb = (iSelectedIndex >= 2 && iSelectedIndex <= 4); - float fReverbAlpha = (bReverb)?1.0f:0.3f; - bool bDelay = (iSelectedIndex ==1 || iSelectedIndex >= 5); - float fDelayAlpha = (bDelay)?1.0f:0.3f; - - m_reverbDecayTime.setEnabled(bReverb); - m_reverbDecayTime.setAlpha(fReverbAlpha); - m_reverbDaming.setEnabled(bReverb); - m_reverbDaming.setAlpha(fReverbAlpha); - m_reverbColoration.setEnabled(bReverb); - m_reverbColoration.setAlpha(fReverbAlpha); - m_reverbPredelay.setEnabled(bReverb); - m_reverbPredelay.setAlpha(fReverbAlpha); - m_reverbFeedback.setEnabled(bReverb); - m_reverbFeedback.setAlpha(fReverbAlpha); - m_reverbType.setEnabled(bReverb); - m_reverbType.setAlpha(fReverbAlpha); - - m_delayTime.setEnabled(bDelay); - m_delayTime.setAlpha(fDelayAlpha); - m_delayRate.setEnabled(bDelay); - m_delayRate.setAlpha(fDelayAlpha); - m_delayFeedback.setEnabled(bDelay); - m_delayFeedback.setAlpha(fDelayAlpha); - m_delayColoration.setEnabled(bDelay); - m_delayColoration.setAlpha(fDelayAlpha); - m_delayDepth.setEnabled(bDelay); - m_delayDepth.setAlpha(fDelayAlpha); - m_delayClock.setEnabled(bDelay); - m_delayClock.setAlpha(fDelayAlpha); - m_delayShape.setEnabled(bDelay); - m_delayShape.setAlpha(fDelayAlpha); -} +} // namespace Trancy +\ No newline at end of file diff --git a/source/jucePlugin/ui2/Virus_Panel3_FxEditor.h b/source/jucePlugin/ui2/Virus_Panel3_FxEditor.h @@ -2,66 +2,71 @@ #include "../PluginProcessor.h" #include "Virus_Buttons.h" - - class VirusParameterBinding; -class FxEditor : public juce::Component +namespace Trancy { -public: - FxEditor(VirusParameterBinding& _parameterBinding, AudioPluginAudioProcessor &_processorRef); - -private: - void DelayReverb(); - void Vocoder(); - Virus::Controller &m_controller; - - // Env Follower - juce::Slider m_envFollowLevel, m_envFollowAttack, m_eEnvFollowRelease; - Buttons::Button3 m_envFollow; - - // Distortion - juce::Slider m_distortionIntensity; - juce::ComboBox m_distortionCurve; - - // Chorus - juce::Slider m_chorusRate, m_chorusDepth, m_chorusFeedback, m_chorusMix, m_chorusDelay; - juce::ComboBox m_choruslfoShape; - - // AnalogBoost - juce::Slider m_analogBoostIntensity, m_AnalogBoostTune; - - // Phaser - juce::Slider m_phaserMix, m_phaserSpread, m_phaserRate, m_phaserDepth, m_phaserFreq, m_phaserFeedback; - juce::ComboBox m_stages; - - // Equalizer - juce::Slider m_equalizerLowGgain, m_equalizerLowFreq, m_equalizerMidGain, m_equalizerMidFreq, m_equalizerMidQ, - m_equalizerHighGgain, m_equalizerHighFreq; - - // Ring Mod - juce::Slider m_ringModMix; - - //Delay/Reverb - juce::Slider m_delayReverbSend; - juce::ComboBox m_delayReverbMode; + - //Delay - juce::Slider m_delayTime, m_delayRate, m_delayFeedback, m_delayColoration, m_delayDepth; - juce::ComboBox m_delayClock; - juce::ComboBox m_delayShape; - - //Reverb - juce::Slider m_reverbDecayTime, m_reverbDaming, m_reverbColoration, m_reverbPredelay, m_reverbFeedback; - juce::ComboBox m_reverbType; - - //Vocoder - juce::Slider m_vocoderCenterFreq, m_vocoderModOffset, m_vocoderModQ, m_vocoderModSpread, m_vocoderCarrQ, - m_vocoderCarrSpread, m_vocoderSpectralBal, m_vocoderBands, m_vocoderAttack, m_vocoderRelease, m_vocoderSourceBal; - - Buttons::Button4 m_vocoderLink; - juce::ComboBox m_vocoderMode; - juce::ComboBox m_vocoderModInput; - - std::unique_ptr<juce::Drawable> m_background; -}; + + class FxEditor : public juce::Component + { + public: + FxEditor(VirusParameterBinding &_parameterBinding, AudioPluginAudioProcessor &_processorRef); + + private: + void DelayReverb(); + void Vocoder(); + Virus::Controller &m_controller; + + // Env Follower + juce::Slider m_envFollowLevel, m_envFollowAttack, m_eEnvFollowRelease; + Buttons::Button3 m_envFollow; + + // Distortion + juce::Slider m_distortionIntensity; + juce::ComboBox m_distortionCurve; + + // Chorus + juce::Slider m_chorusRate, m_chorusDepth, m_chorusFeedback, m_chorusMix, m_chorusDelay; + juce::ComboBox m_choruslfoShape; + + // AnalogBoost + juce::Slider m_analogBoostIntensity, m_AnalogBoostTune; + + // Phaser + juce::Slider m_phaserMix, m_phaserSpread, m_phaserRate, m_phaserDepth, m_phaserFreq, m_phaserFeedback; + juce::ComboBox m_stages; + + // Equalizer + juce::Slider m_equalizerLowGgain, m_equalizerLowFreq, m_equalizerMidGain, m_equalizerMidFreq, m_equalizerMidQ, + m_equalizerHighGgain, m_equalizerHighFreq; + + // Ring Mod + juce::Slider m_ringModMix; + + // Delay/Reverb + juce::Slider m_delayReverbSend; + juce::ComboBox m_delayReverbMode; + + // Delay + juce::Slider m_delayTime, m_delayRate, m_delayFeedback, m_delayColoration, m_delayDepth; + juce::ComboBox m_delayClock; + juce::ComboBox m_delayShape; + + // Reverb + juce::Slider m_reverbDecayTime, m_reverbDaming, m_reverbColoration, m_reverbPredelay, m_reverbFeedback; + juce::ComboBox m_reverbType; + + // Vocoder + juce::Slider m_vocoderCenterFreq, m_vocoderModOffset, m_vocoderModQ, m_vocoderModSpread, m_vocoderCarrQ, + m_vocoderCarrSpread, m_vocoderSpectralBal, m_vocoderBands, m_vocoderAttack, m_vocoderRelease, + m_vocoderSourceBal; + + Buttons::Button4 m_vocoderLink; + juce::ComboBox m_vocoderMode; + juce::ComboBox m_vocoderModInput; + + std::unique_ptr<juce::Drawable> m_background; + }; +} // namespace Trancy +\ No newline at end of file diff --git a/source/jucePlugin/ui2/Virus_Panel4_ArpEditor.cpp b/source/jucePlugin/ui2/Virus_Panel4_ArpEditor.cpp @@ -4,374 +4,404 @@ #include "../VirusParameterBinding.h" #include "VirusEditor.h" -using namespace juce; -using namespace virusLib; +namespace Trancy +{ + + using namespace juce; + using namespace virusLib; + static uint8_t g_playMode = 0; + ArpEditor::ArpEditor(::VirusParameterBinding &_parameterBinding, AudioPluginAudioProcessor &_processorRef) : + processorRef(_processorRef), m_properties(_processorRef.getController().getConfig()), + m_controller(_processorRef.getController()), m_parameterBinding(_parameterBinding) + { + setupBackground(*this, m_background, BinaryData::panel_4_png, BinaryData::panel_4_pngSize); + setBounds(m_background->getDrawableBounds().toNearestIntEdges()); + + int xPosMargin = 10; + + // Inputs + addAndMakeVisible(m_inputMode); + m_inputMode.setBounds(1488 + xPosMargin - comboBox3Width / 2, 821 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + addAndMakeVisible(m_inputSelect); + m_inputSelect.setBounds(1488 + xPosMargin - comboBox3Width / 2, 921 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + + _parameterBinding.bind(m_inputMode, Virus::Param_InputMode); + _parameterBinding.bind(m_inputSelect, Virus::Param_InputSelect); + + // Arpeggiator + constexpr auto y = 18; + for (auto *s : {&m_globalTempo, &m_noteLength, &m_noteSwing}) + setupRotary(*this, *s); + + m_globalTempo.setBounds(1970 - knobSize / 2, 613 - knobSize / 2, knobSize, knobSize); + m_noteLength.setBounds(1424 - knobSize / 2, 613 - knobSize / 2, knobSize, knobSize); + m_noteSwing.setBounds(1574 - knobSize / 2, 613 - knobSize / 2, knobSize, knobSize); + + for (auto *c : {&m_mode, &m_pattern, &m_octaveRange, &m_resolution}) + addAndMakeVisible(c); + + m_mode.setBounds(1228 + xPosMargin - comboBox3Width / 2, 558 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + m_pattern.setBounds(1228 + xPosMargin - comboBox3Width / 2, 656 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + m_resolution.setBounds(1773 + xPosMargin - comboBox3Width / 2, 656 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + m_octaveRange.setBounds(1773 + xPosMargin - comboBox3Width / 2, 558 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + + addAndMakeVisible(m_arpHold); + + m_arpHold.setBounds(2129 - m_arpHold.kWidth / 2, 613 - m_arpHold.kHeight / 2, m_arpHold.kWidth, + m_arpHold.kHeight); + m_globalTempo.setEnabled(false); + m_globalTempo.setAlpha(0.3f); + + _parameterBinding.bind(m_globalTempo, Virus::Param_ClockTempo, 0); + _parameterBinding.bind(m_noteLength, Virus::Param_ArpNoteLength); + _parameterBinding.bind(m_noteSwing, Virus::Param_ArpSwing); + _parameterBinding.bind(m_mode, Virus::Param_ArpMode); + _parameterBinding.bind(m_pattern, Virus::Param_ArpPatternSelect); + _parameterBinding.bind(m_octaveRange, Virus::Param_ArpOctaveRange); + _parameterBinding.bind(m_resolution, Virus::Param_ArpClock); + _parameterBinding.bind(m_arpHold, Virus::Param_ArpHoldEnable); + + // SoftKnobs + m_softknobFunc1.setBounds(1756 + xPosMargin - comboBox3Width / 2, 822 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + m_softknobFunc2.setBounds(1756 + xPosMargin - comboBox3Width / 2, 921 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + m_softknobName1.setBounds(1983 + xPosMargin - comboBox3Width / 2, 822 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + m_softknobName2.setBounds(1983 + xPosMargin - comboBox3Width / 2, 921 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + + for (auto *c : {&m_softknobFunc1, &m_softknobFunc2, &m_softknobName1, &m_softknobName2}) + addAndMakeVisible(c); + + _parameterBinding.bind(m_softknobName1, Virus::Param_SoftKnob1ShortName); + _parameterBinding.bind(m_softknobName2, Virus::Param_SoftKnob2ShortName); + _parameterBinding.bind(m_softknobFunc1, Virus::Param_SoftKnob1Single); + _parameterBinding.bind(m_softknobFunc2, Virus::Param_SoftKnob2Single); + + // PatchSettings + for (auto *s : {&m_patchVolume, &m_panning, &m_outputBalance, &m_transpose}) + setupRotary(*this, *s); + + for (auto *c : {&m_patchVolume, &m_panning, &m_outputBalance, &m_transpose}) + addAndMakeVisible(c); + + m_patchVolume.setBounds(1428 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); + m_panning.setBounds(1572 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); + m_outputBalance.setBounds(1715 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); + m_transpose.setBounds(1862 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); + + for (auto *c : {&m_keyMode, &m_bendUp, &m_bendDown, &m_bendScale, &m_smoothMode, &m_cat1, &m_cat2}) + addAndMakeVisible(c); + + m_keyMode.setBounds(1232 + xPosMargin - comboBox3Width / 2, 113 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + m_smoothMode.setBounds(1232 + xPosMargin - comboBox3Width / 2, 259 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + m_bendScale.setBounds(1436 + xPosMargin - comboBox3Width / 2, 259 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + m_bendUp.setBounds(1641 + xPosMargin - comboBox3Width / 2, 259 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + m_bendDown.setBounds(1848 + xPosMargin - comboBox3Width / 2, 259 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + + m_cat1.setBounds(1232 + xPosMargin - comboBox3Width / 2, 382 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + m_cat2.setBounds(1436 + xPosMargin - comboBox3Width / 2, 382 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + + _parameterBinding.bind(m_patchVolume, Virus::Param_PatchVolume); + _parameterBinding.bind(m_panning, Virus::Param_Panorama); + //_parameterBinding.bind(m_outputBalance, Virus::Param_SecondOutputBalance); + _parameterBinding.bind(m_transpose, Virus::Param_Transpose); + _parameterBinding.bind(m_keyMode, Virus::Param_KeyMode); + _parameterBinding.bind(m_bendUp, Virus::Param_BenderRangeUp); + _parameterBinding.bind(m_bendDown, Virus::Param_BenderRangeDown); + _parameterBinding.bind(m_bendScale, Virus::Param_BenderScale); + _parameterBinding.bind(m_smoothMode, Virus::Param_ControlSmoothMode); + _parameterBinding.bind(m_cat1, Virus::Param_Category1); + _parameterBinding.bind(m_cat2, Virus::Param_Category2); + _parameterBinding.bind(m_secondaryOutput, Virus::Param_PartOutputSelect); + + // Channels + int iMarginYChannels = 118; + int iMarginXChannels = 0; + int iIndex = 0; + + for (auto pt = 0; pt < 16; pt++) + { + if (pt == 8) + { + iIndex = 0; + iMarginXChannels = 549; + } + + // Buttons + m_partSelect[pt].setBounds(95 - m_partSelect[pt].kWidth / 2 + iMarginXChannels, + 96 - m_partSelect[pt].kHeight / 2 + iIndex * (iMarginYChannels), + m_partSelect[pt].kWidth, m_partSelect[pt].kHeight); + m_partSelect[pt].setRadioGroupId(kPartGroupId); + m_partSelect[pt].setClickingTogglesState(true); + m_partSelect[pt].onClick = [this, pt]() { this->changePart(pt); }; + addAndMakeVisible(m_partSelect[pt]); + + m_presetNames[pt].setBounds(245 - 225 / 2 + iMarginXChannels, 97 - 70 / 2 + iIndex * (iMarginYChannels), + 225, 70); + m_presetNames[pt].setText(m_controller.getCurrentPartPresetName(pt), dontSendNotification); + m_presetNames[pt].setFont(Font("Register", "Normal", 23.f)); + m_presetNames[pt].setJustificationType(Justification::left); + + addAndMakeVisible(m_presetNames[pt]); + + // Knobs + for (auto *s : {&m_partVolumes[pt], &m_partPans[pt]}) + { + setupRotary(*this, *s); + } + + m_partVolumes[pt].setLookAndFeel(&m_lookAndFeelSmallButton); + m_partVolumes[pt].setBounds(407 - knobSizeSmall / 2 + iMarginXChannels, + 98 - knobSizeSmall / 2 + iIndex * (iMarginYChannels), knobSizeSmall, + knobSizeSmall); + _parameterBinding.bind(m_partVolumes[pt], Virus::Param_PartVolume, pt); + addAndMakeVisible(m_partVolumes[pt]); + + m_partPans[pt].setLookAndFeel(&m_lookAndFeelSmallButton); + m_partPans[pt].setBounds(495 - knobSizeSmall / 2 + iMarginXChannels, + 98 - knobSizeSmall / 2 + iIndex * (iMarginYChannels), knobSizeSmall, + knobSizeSmall); + _parameterBinding.bind(m_partPans[pt], Virus::Param_Panorama, pt); + addAndMakeVisible(m_partPans[pt]); + + iIndex++; + } + + m_btWorkingMode.setBounds(1203 - m_btWorkingMode.kWidth / 2, 868 - m_btWorkingMode.kHeight / 2, + m_btWorkingMode.kWidth, m_btWorkingMode.kHeight); + addAndMakeVisible(m_btWorkingMode); + m_btWorkingMode.onClick = [this]() { + if (m_btWorkingMode.getToggleState() == 1) + { + setPlayMode(virusLib::PlayMode::PlayModeSingle); + } + else + { + setPlayMode(virusLib::PlayMode::PlayModeMulti); + } + updatePlayModeButtons(); + }; + + m_partSelect[m_controller.getCurrentPart()].setToggleState(true, NotificationType::dontSendNotification); + refreshParts(); + + MidiInit(); + } + + ArpEditor::~ArpEditor() + { + for (auto pt = 0; pt < 16; pt++) + { + m_partVolumes[pt].setLookAndFeel(nullptr); + m_partPans[pt].setLookAndFeel(nullptr); + } + } + + void ArpEditor::MidiInit() + { + // MIDI settings + String midiIn = m_properties->getValue("midi_input", ""); + String midiOut = m_properties->getValue("midi_output", ""); + + if (midiIn != "") + { + processorRef.setMidiInput(midiIn); + } + if (midiOut != "") + { + processorRef.setMidiOutput(midiOut); + } -static uint8_t g_playMode = 0; + m_cmbMidiInput.setBounds(2138 - 250 / 2, 81 - 47 / 2, 250, 47); + m_cmbMidiOutput.setBounds(2138 - 250 / 2, 178 - 47 / 2, 250, 47); -ArpEditor::ArpEditor(VirusParameterBinding &_parameterBinding, AudioPluginAudioProcessor &_processorRef): - processorRef(_processorRef), m_properties(_processorRef.getController().getConfig()), m_controller(_processorRef.getController()), m_parameterBinding(_parameterBinding) -{ - setupBackground(*this, m_background, BinaryData::panel_4_png, BinaryData::panel_4_pngSize); - setBounds(m_background->getDrawableBounds().toNearestIntEdges()); - - int xPosMargin = 10; - - //Inputs - addAndMakeVisible(m_inputMode); - m_inputMode.setBounds(1488 + xPosMargin - comboBox3Width/2, 821 - comboBox3Height/2, comboBox3Width, comboBox3Height); - addAndMakeVisible(m_inputSelect); - m_inputSelect.setBounds(1488 + xPosMargin - comboBox3Width/2, 921 - comboBox3Height/2, comboBox3Width, comboBox3Height); - - _parameterBinding.bind(m_inputMode, Virus::Param_InputMode); - _parameterBinding.bind(m_inputSelect, Virus::Param_InputSelect); - - //Arpeggiator - constexpr auto y = 18; - for (auto *s : {&m_globalTempo, &m_noteLength, &m_noteSwing}) - setupRotary(*this, *s); - - m_globalTempo.setBounds(1970 - knobSize / 2, 613 - knobSize / 2, knobSize, knobSize); - m_noteLength.setBounds(1424 - knobSize / 2, 613 - knobSize / 2, knobSize, knobSize); - m_noteSwing.setBounds(1574 - knobSize / 2, 613 - knobSize / 2, knobSize, knobSize); - - for (auto *c : {&m_mode, &m_pattern, &m_octaveRange, &m_resolution}) - addAndMakeVisible(c); - - m_mode.setBounds(1228 + xPosMargin - comboBox3Width/2, 558 - comboBox3Height/2, comboBox3Width, comboBox3Height); - m_pattern.setBounds(1228 + xPosMargin - comboBox3Width/2, 656 - comboBox3Height/2, comboBox3Width, comboBox3Height); - m_resolution.setBounds(1773 + xPosMargin - comboBox3Width/2, 656 - comboBox3Height/2, comboBox3Width, comboBox3Height); - m_octaveRange.setBounds(1773 + xPosMargin - comboBox3Width/2, 558 - comboBox3Height/2, comboBox3Width, comboBox3Height); - - addAndMakeVisible(m_arpHold); - - m_arpHold.setBounds(2129 - m_arpHold.kWidth/ 2, 613 - m_arpHold.kHeight / 2, m_arpHold.kWidth, m_arpHold.kHeight); - m_globalTempo.setEnabled(false); - m_globalTempo.setAlpha(0.3f); - - _parameterBinding.bind(m_globalTempo, Virus::Param_ClockTempo, 0); - _parameterBinding.bind(m_noteLength, Virus::Param_ArpNoteLength); - _parameterBinding.bind(m_noteSwing, Virus::Param_ArpSwing); - _parameterBinding.bind(m_mode, Virus::Param_ArpMode); - _parameterBinding.bind(m_pattern, Virus::Param_ArpPatternSelect); - _parameterBinding.bind(m_octaveRange, Virus::Param_ArpOctaveRange); - _parameterBinding.bind(m_resolution, Virus::Param_ArpClock); - _parameterBinding.bind(m_arpHold, Virus::Param_ArpHoldEnable); - - //SoftKnobs - m_softknobFunc1.setBounds(1756 + xPosMargin - comboBox3Width/2, 822 - comboBox3Height/2, comboBox3Width, comboBox3Height); - m_softknobFunc2.setBounds(1756 + xPosMargin - comboBox3Width/2, 921 - comboBox3Height/2, comboBox3Width, comboBox3Height); - m_softknobName1.setBounds(1983 + xPosMargin - comboBox3Width/2, 822 - comboBox3Height/2, comboBox3Width, comboBox3Height); - m_softknobName2.setBounds(1983 + xPosMargin - comboBox3Width/2, 921 - comboBox3Height/2, comboBox3Width, comboBox3Height); - - for (auto *c : {&m_softknobFunc1, &m_softknobFunc2, &m_softknobName1, &m_softknobName2}) - addAndMakeVisible(c); - - _parameterBinding.bind(m_softknobName1, Virus::Param_SoftKnob1ShortName); - _parameterBinding.bind(m_softknobName2, Virus::Param_SoftKnob2ShortName); - _parameterBinding.bind(m_softknobFunc1, Virus::Param_SoftKnob1Single); - _parameterBinding.bind(m_softknobFunc2, Virus::Param_SoftKnob2Single); - - //PatchSettings - for (auto *s : {&m_patchVolume, &m_panning, &m_outputBalance, &m_transpose}) - setupRotary(*this, *s); - - for (auto *c : {&m_patchVolume, &m_panning, &m_outputBalance, &m_transpose}) - addAndMakeVisible(c); - - m_patchVolume.setBounds(1428 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); - m_panning.setBounds(1572 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); - m_outputBalance.setBounds(1715 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); - m_transpose.setBounds(1862 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); - - for (auto *c : {&m_keyMode, &m_bendUp, &m_bendDown, &m_bendScale, &m_smoothMode, &m_cat1, &m_cat2}) - addAndMakeVisible(c); - - m_keyMode.setBounds(1232 + xPosMargin - comboBox3Width/2, 113 - comboBox3Height/2, comboBox3Width, comboBox3Height); - m_smoothMode.setBounds(1232 + xPosMargin - comboBox3Width/2, 259 - comboBox3Height/2, comboBox3Width, comboBox3Height); - m_bendScale.setBounds(1436 + xPosMargin - comboBox3Width/2, 259 - comboBox3Height/2, comboBox3Width, comboBox3Height); - m_bendUp.setBounds(1641 + xPosMargin - comboBox3Width/2, 259 - comboBox3Height/2, comboBox3Width, comboBox3Height); - m_bendDown.setBounds(1848 + xPosMargin - comboBox3Width/2, 259 - comboBox3Height/2, comboBox3Width, comboBox3Height); - - m_cat1.setBounds(1232 + xPosMargin - comboBox3Width/2, 382 - comboBox3Height/2, comboBox3Width, comboBox3Height); - m_cat2.setBounds(1436 + xPosMargin - comboBox3Width/2, 382 - comboBox3Height/2, comboBox3Width, comboBox3Height); - - _parameterBinding.bind(m_patchVolume, Virus::Param_PatchVolume); - _parameterBinding.bind(m_panning, Virus::Param_Panorama); - //_parameterBinding.bind(m_outputBalance, Virus::Param_SecondOutputBalance); - _parameterBinding.bind(m_transpose, Virus::Param_Transpose); - _parameterBinding.bind(m_keyMode, Virus::Param_KeyMode); - _parameterBinding.bind(m_bendUp, Virus::Param_BenderRangeUp); - _parameterBinding.bind(m_bendDown, Virus::Param_BenderRangeDown); - _parameterBinding.bind(m_bendScale, Virus::Param_BenderScale); - _parameterBinding.bind(m_smoothMode, Virus::Param_ControlSmoothMode); - _parameterBinding.bind(m_cat1, Virus::Param_Category1); - _parameterBinding.bind(m_cat2, Virus::Param_Category2); - _parameterBinding.bind(m_secondaryOutput, Virus::Param_PartOutputSelect); - - //Channels - int iMarginYChannels = 118; - int iMarginXChannels = 0; - int iIndex = 0; - - for (auto pt = 0; pt < 16; pt++) - { - if (pt==8) - { - iIndex=0; - iMarginXChannels=549; - } - - //Buttons - m_partSelect[pt].setBounds(95 - m_partSelect[pt].kWidth/2 + iMarginXChannels, 96 - m_partSelect[pt].kHeight/2 + iIndex*(iMarginYChannels), m_partSelect[pt].kWidth, m_partSelect[pt].kHeight); - m_partSelect[pt].setRadioGroupId(kPartGroupId); - m_partSelect[pt].setClickingTogglesState(true); - m_partSelect[pt].onClick = [this, pt]() {this->changePart(pt);}; - addAndMakeVisible(m_partSelect[pt]); - - m_presetNames[pt].setBounds(245 - 225/2 + iMarginXChannels, 97 - 70/2 + iIndex * (iMarginYChannels), 225, 70); - m_presetNames[pt].setText(m_controller.getCurrentPartPresetName(pt), dontSendNotification); - m_presetNames[pt].setFont(Font("Register", "Normal", 23.f)); - m_presetNames[pt].setJustificationType(Justification::left); - - addAndMakeVisible(m_presetNames[pt]); - - //Knobs - for (auto *s : {&m_partVolumes[pt], &m_partPans[pt]}) - { - setupRotary(*this, *s); - } - - m_partVolumes[pt].setLookAndFeel(&m_lookAndFeelSmallButton); - m_partVolumes[pt].setBounds(407 - knobSizeSmall / 2 + iMarginXChannels, 98 - knobSizeSmall / 2 + iIndex * (iMarginYChannels), knobSizeSmall, knobSizeSmall); - _parameterBinding.bind(m_partVolumes[pt], Virus::Param_PartVolume, pt); - addAndMakeVisible(m_partVolumes[pt]); - - m_partPans[pt].setLookAndFeel(&m_lookAndFeelSmallButton); - m_partPans[pt].setBounds(495 - knobSizeSmall / 2 + iMarginXChannels, 98 - knobSizeSmall / 2 + iIndex * (iMarginYChannels), knobSizeSmall, knobSizeSmall); - _parameterBinding.bind(m_partPans[pt], Virus::Param_Panorama, pt); - addAndMakeVisible(m_partPans[pt]); - - iIndex++; - } - - m_btWorkingMode.setBounds(1203 - m_btWorkingMode.kWidth / 2, 868 - m_btWorkingMode.kHeight / 2, m_btWorkingMode.kWidth, m_btWorkingMode.kHeight); - addAndMakeVisible(m_btWorkingMode); - m_btWorkingMode.onClick = [this]() - { - if (m_btWorkingMode.getToggleState()==1) + addAndMakeVisible(m_cmbMidiInput); + addAndMakeVisible(m_cmbMidiOutput); + + m_cmbMidiInput.setTextWhenNoChoicesAvailable("No MIDI Inputs Enabled"); + auto midiInputs = MidiInput::getAvailableDevices(); + StringArray midiInputNames; + midiInputNames.add(" - Midi In - "); + auto inIndex = 0; + + for (int i = 0; i < midiInputs.size(); i++) + { + const auto input = midiInputs[i]; + if (processorRef.getMidiInput() != nullptr && + input.identifier == processorRef.getMidiInput()->getIdentifier()) + { + inIndex = i + 1; + } + midiInputNames.add(input.name); + } + + m_cmbMidiInput.addItemList(midiInputNames, 1); + m_cmbMidiInput.setSelectedItemIndex(inIndex, dontSendNotification); + m_cmbMidiOutput.setTextWhenNoChoicesAvailable("No MIDI Outputs Enabled"); + auto midiOutputs = MidiOutput::getAvailableDevices(); + StringArray midiOutputNames; + midiOutputNames.add(" - Midi Out - "); + auto outIndex = 0; + + for (int i = 0; i < midiOutputs.size(); i++) + { + const auto output = midiOutputs[i]; + if (processorRef.getMidiOutput() != nullptr && + output.identifier == processorRef.getMidiOutput()->getIdentifier()) + { + outIndex = i + 1; + } + midiOutputNames.add(output.name); + } + + m_cmbMidiOutput.addItemList(midiOutputNames, 1); + m_cmbMidiOutput.setSelectedItemIndex(outIndex, dontSendNotification); + m_cmbMidiInput.onChange = [this]() { updateMidiInput(m_cmbMidiInput.getSelectedItemIndex()); }; + m_cmbMidiOutput.onChange = [this]() { updateMidiOutput(m_cmbMidiOutput.getSelectedItemIndex()); }; + } + + + void ArpEditor::refreshParts() + { + const auto multiMode = m_controller.isMultiMode(); + for (auto pt = 0; pt < 16; pt++) + { + bool singlePartOrInMulti = pt == 0 || multiMode; + float fAlpha = (multiMode) ? 1.0 : 0.3; + + if (pt > 0) + { + m_partVolumes[pt].setEnabled(singlePartOrInMulti); + m_partVolumes[pt].setAlpha(fAlpha); + m_partPans[pt].setEnabled(singlePartOrInMulti); + m_partPans[pt].setAlpha(fAlpha); + m_partSelect[pt].setEnabled(singlePartOrInMulti); + m_partSelect[pt].setAlpha(fAlpha); + m_presetNames[pt].setEnabled(singlePartOrInMulti); + m_presetNames[pt].setAlpha(fAlpha); + } + if (singlePartOrInMulti) + m_presetNames[pt].setText(m_controller.getCurrentPartPresetName(pt), dontSendNotification); + else + m_presetNames[pt].setText("", dontSendNotification); + } + + updatePlayModeButtons(); + } + + void ArpEditor::changePart(uint8_t _part) + { + for (auto &p : m_partSelect) + { + p.setToggleState(false, dontSendNotification); + } + m_partSelect[_part].setToggleState(true, dontSendNotification); + m_parameterBinding.setPart(_part); + getParentComponent()->postCommandMessage(VirusEditor::Commands::UpdateParts); + getParentComponent()->postCommandMessage(VirusEditor::Commands::Rebind); + } + + void ArpEditor::setPlayMode(uint8_t _mode) + { + m_controller.getParameter(Virus::Param_PlayMode)->setValue(_mode); + if (_mode == virusLib::PlayModeSingle && m_controller.getCurrentPart() != 0) + { + changePart(0); + } + getParentComponent()->postCommandMessage(VirusEditor::Commands::Rebind); + } + + + void ArpEditor::updatePlayModeButtons() + { + const auto modeParam = m_controller.getParameter(Virus::Param_PlayMode, 0); + if (modeParam == nullptr) + { + return; + } + const auto _mode = (int)modeParam->getValue(); + if (_mode == virusLib::PlayModeSingle) { - setPlayMode(virusLib::PlayMode::PlayModeSingle); - } - else + m_btWorkingMode.setToggleState(true, dontSendNotification); + } + else if (_mode == virusLib::PlayModeMulti || _mode == virusLib::PlayModeMultiSingle) { - setPlayMode(virusLib::PlayMode::PlayModeMulti); - } - updatePlayModeButtons(); - }; + m_btWorkingMode.setToggleState(false, dontSendNotification); + } + } - m_partSelect[m_controller.getCurrentPart()].setToggleState(true, NotificationType::dontSendNotification); - refreshParts(); + void ArpEditor::updateMidiInput(int index) + { + auto list = MidiInput::getAvailableDevices(); - MidiInit(); -} + if (index == 0) + { + m_properties->setValue("midi_input", ""); + m_properties->save(); + m_lastInputIndex = index; + m_cmbMidiInput.setSelectedItemIndex(index, dontSendNotification); + return; + } + index--; + auto newInput = list[index]; + + if (!deviceManager.isMidiInputDeviceEnabled(newInput.identifier)) + deviceManager.setMidiInputDeviceEnabled(newInput.identifier, true); + + if (!processorRef.setMidiInput(newInput.identifier)) + { + m_cmbMidiInput.setSelectedItemIndex(0, dontSendNotification); + m_lastInputIndex = 0; + return; + } -ArpEditor::~ArpEditor() -{ - for (auto pt = 0; pt < 16; pt++) - { - m_partVolumes[pt].setLookAndFeel(nullptr); - m_partPans[pt].setLookAndFeel(nullptr); - } -} - -void ArpEditor::MidiInit() -{ - //MIDI settings - String midiIn = m_properties->getValue("midi_input", ""); - String midiOut = m_properties->getValue("midi_output", ""); - - if (midiIn != "") - { - processorRef.setMidiInput(midiIn); - } - if (midiOut != "") - { - processorRef.setMidiOutput(midiOut); - } - - m_cmbMidiInput.setBounds(2138 - 250 / 2, 81 - 47 / 2, 250, 47); - m_cmbMidiOutput.setBounds(2138 - 250 / 2, 178 - 47 / 2, 250, 47); - - addAndMakeVisible(m_cmbMidiInput); - addAndMakeVisible(m_cmbMidiOutput); - - m_cmbMidiInput.setTextWhenNoChoicesAvailable("No MIDI Inputs Enabled"); - auto midiInputs = MidiInput::getAvailableDevices(); - StringArray midiInputNames; - midiInputNames.add(" - Midi In - "); - auto inIndex = 0; - - for (int i = 0; i < midiInputs.size(); i++) - { - const auto input = midiInputs[i]; - if (processorRef.getMidiInput() != nullptr && input.identifier == processorRef.getMidiInput()->getIdentifier()) - { - inIndex = i + 1; - } - midiInputNames.add(input.name); - } - - m_cmbMidiInput.addItemList(midiInputNames, 1); - m_cmbMidiInput.setSelectedItemIndex(inIndex, dontSendNotification); - m_cmbMidiOutput.setTextWhenNoChoicesAvailable("No MIDI Outputs Enabled"); - auto midiOutputs = MidiOutput::getAvailableDevices(); - StringArray midiOutputNames; - midiOutputNames.add(" - Midi Out - "); - auto outIndex = 0; - - for (int i = 0; i < midiOutputs.size(); i++) - { - const auto output = midiOutputs[i]; - if (processorRef.getMidiOutput() != nullptr && - output.identifier == processorRef.getMidiOutput()->getIdentifier()) - { - outIndex = i + 1; - } - midiOutputNames.add(output.name); - } - - m_cmbMidiOutput.addItemList(midiOutputNames, 1); - m_cmbMidiOutput.setSelectedItemIndex(outIndex, dontSendNotification); - m_cmbMidiInput.onChange = [this]() { updateMidiInput(m_cmbMidiInput.getSelectedItemIndex()); }; - m_cmbMidiOutput.onChange = [this]() { updateMidiOutput(m_cmbMidiOutput.getSelectedItemIndex()); }; -} - - -void ArpEditor::refreshParts() -{ - const auto multiMode = m_controller.isMultiMode(); - for (auto pt = 0; pt < 16; pt++) - { - bool singlePartOrInMulti = pt == 0 || multiMode; - float fAlpha=(multiMode)?1.0:0.3; - - if (pt>0) - { - m_partVolumes[pt].setEnabled(singlePartOrInMulti); - m_partVolumes[pt].setAlpha(fAlpha); - m_partPans[pt].setEnabled(singlePartOrInMulti); - m_partPans[pt].setAlpha(fAlpha); - m_partSelect[pt].setEnabled(singlePartOrInMulti); - m_partSelect[pt].setAlpha(fAlpha); - m_presetNames[pt].setEnabled(singlePartOrInMulti); - m_presetNames[pt].setAlpha(fAlpha); - } - if (singlePartOrInMulti) - m_presetNames[pt].setText(m_controller.getCurrentPartPresetName(pt), dontSendNotification); - else - m_presetNames[pt].setText("", dontSendNotification); - } - - updatePlayModeButtons(); -} - -void ArpEditor::changePart(uint8_t _part) -{ - for (auto &p : m_partSelect) - { - p.setToggleState(false, dontSendNotification); - } - m_partSelect[_part].setToggleState(true, dontSendNotification); - m_parameterBinding.setPart(_part); - getParentComponent()->postCommandMessage(VirusEditor::Commands::UpdateParts); - getParentComponent()->postCommandMessage(VirusEditor::Commands::Rebind); -} - -void ArpEditor::setPlayMode(uint8_t _mode) -{ - m_controller.getParameter(Virus::Param_PlayMode)->setValue(_mode); - if (_mode == virusLib::PlayModeSingle && m_controller.getCurrentPart() != 0) - { - changePart(0); - } - getParentComponent()->postCommandMessage(VirusEditor::Commands::Rebind); -} + m_properties->setValue("midi_input", newInput.identifier); + m_properties->save(); + m_cmbMidiInput.setSelectedItemIndex(index + 1, dontSendNotification); + m_lastInputIndex = index; + } -void ArpEditor::updatePlayModeButtons() -{ - const auto modeParam = m_controller.getParameter(Virus::Param_PlayMode, 0); - if (modeParam == nullptr) { - return; - } - const auto _mode = (int)modeParam->getValue(); - if (_mode == virusLib::PlayModeSingle) - { - m_btWorkingMode.setToggleState(true, dontSendNotification); - } - else if (_mode == virusLib::PlayModeMulti || _mode == virusLib::PlayModeMultiSingle) - { - m_btWorkingMode.setToggleState(false, dontSendNotification); - } -} - -void ArpEditor::updateMidiInput(int index) -{ - auto list = MidiInput::getAvailableDevices(); - - if (index == 0) - { - m_properties->setValue("midi_input", ""); - m_properties->save(); - m_lastInputIndex = index; - m_cmbMidiInput.setSelectedItemIndex(index, dontSendNotification); - return; - } - index--; - auto newInput = list[index]; - - if (!deviceManager.isMidiInputDeviceEnabled(newInput.identifier)) - deviceManager.setMidiInputDeviceEnabled(newInput.identifier, true); - - if (!processorRef.setMidiInput(newInput.identifier)) - { - m_cmbMidiInput.setSelectedItemIndex(0, dontSendNotification); - m_lastInputIndex = 0; - return; - } - - m_properties->setValue("midi_input", newInput.identifier); - m_properties->save(); - - m_cmbMidiInput.setSelectedItemIndex(index + 1, dontSendNotification); - m_lastInputIndex = index; -} - -void ArpEditor::updateMidiOutput(int index) -{ - auto list = MidiOutput::getAvailableDevices(); - - if (index == 0) - { - m_properties->setValue("midi_output", ""); - m_properties->save(); - m_cmbMidiOutput.setSelectedItemIndex(index, dontSendNotification); - m_lastOutputIndex = index; - processorRef.setMidiOutput(""); - return; - } - index--; - auto newOutput = list[index]; - if (!processorRef.setMidiOutput(newOutput.identifier)) - { - m_cmbMidiOutput.setSelectedItemIndex(0, dontSendNotification); - m_lastOutputIndex = 0; - return; - } - m_properties->setValue("midi_output", newOutput.identifier); - m_properties->save(); - - m_cmbMidiOutput.setSelectedItemIndex(index + 1, dontSendNotification); - m_lastOutputIndex = index; -} + void ArpEditor::updateMidiOutput(int index) + { + auto list = MidiOutput::getAvailableDevices(); + + if (index == 0) + { + m_properties->setValue("midi_output", ""); + m_properties->save(); + m_cmbMidiOutput.setSelectedItemIndex(index, dontSendNotification); + m_lastOutputIndex = index; + processorRef.setMidiOutput(""); + return; + } + index--; + auto newOutput = list[index]; + if (!processorRef.setMidiOutput(newOutput.identifier)) + { + m_cmbMidiOutput.setSelectedItemIndex(0, dontSendNotification); + m_lastOutputIndex = 0; + return; + } + m_properties->setValue("midi_output", newOutput.identifier); + m_properties->save(); + + m_cmbMidiOutput.setSelectedItemIndex(index + 1, dontSendNotification); + m_lastOutputIndex = index; + } +} // namespace Trancy +\ No newline at end of file diff --git a/source/jucePlugin/ui2/Virus_Panel4_ArpEditor.h b/source/jucePlugin/ui2/Virus_Panel4_ArpEditor.h @@ -5,64 +5,67 @@ #include <juce_gui_extra/juce_gui_extra.h> #include "../VirusController.h" #include "Virus_LookAndFeel.h" - class VirusParameterBinding; - -class ArpEditor : public juce::Component +namespace Trancy { -public: - ArpEditor(VirusParameterBinding &_parameterBinding, AudioPluginAudioProcessor &_processorRef); - ~ArpEditor() override; + + class ArpEditor : public juce::Component + { + public: + ArpEditor(VirusParameterBinding &_parameterBinding, AudioPluginAudioProcessor &_processorRef); + ~ArpEditor() override; + + static constexpr auto kPartGroupId = 0x3FBBC; + void refreshParts(); + + private: + void updateMidiInput(int index); + void updateMidiOutput(int index); + void MidiInit(); + VirusUI::LookAndFeelSmallButton m_lookAndFeelSmallButton; + + // WorkingMode + juce::ComboBox m_WorkingMode; + + // Channels + void changePart(uint8_t _part); + void setPlayMode(uint8_t _mode); + void updatePlayModeButtons(); + Virus::Controller &m_controller; + VirusParameterBinding &m_parameterBinding; - static constexpr auto kPartGroupId = 0x3FBBC; - void refreshParts(); -private: - void updateMidiInput(int index); - void updateMidiOutput(int index); - void MidiInit(); - Virus::LookAndFeelSmallButton m_lookAndFeelSmallButton; + Buttons::Button3 m_partSelect[16]; + juce::Label m_presetNames[16]; + juce::Slider m_partVolumes[16]; + juce::Slider m_partPans[16]; - //WorkingMode - juce::ComboBox m_WorkingMode; + Buttons::Button2 m_btWorkingMode; - //Channels - void changePart(uint8_t _part); - void setPlayMode(uint8_t _mode); - void updatePlayModeButtons(); - Virus::Controller &m_controller; - VirusParameterBinding &m_parameterBinding; + // MIDI Settings + juce::AudioDeviceManager deviceManager; + juce::ComboBox m_cmbMidiInput; + juce::ComboBox m_cmbMidiOutput; + int m_lastInputIndex = 0; + int m_lastOutputIndex = 0; + juce::PropertiesFile *m_properties; + AudioPluginAudioProcessor &processorRef; - Buttons::Button3 m_partSelect[16]; - juce::Label m_presetNames[16]; - juce::Slider m_partVolumes[16]; - juce::Slider m_partPans[16]; - - Buttons::Button2 m_btWorkingMode; + // Inputs + juce::ComboBox m_inputMode, m_inputSelect; - //MIDI Settings - juce::AudioDeviceManager deviceManager; - juce::ComboBox m_cmbMidiInput; - juce::ComboBox m_cmbMidiOutput; - int m_lastInputIndex = 0; - int m_lastOutputIndex = 0; - juce::PropertiesFile *m_properties; - AudioPluginAudioProcessor &processorRef; + // Arpeggiator + juce::Slider m_globalTempo, m_noteLength, m_noteSwing; + juce::ComboBox m_mode, m_pattern, m_octaveRange, m_resolution; + Buttons::Button3 m_arpHold; - //Inputs - juce::ComboBox m_inputMode, m_inputSelect; - - //Arpeggiator - juce::Slider m_globalTempo, m_noteLength, m_noteSwing; - juce::ComboBox m_mode, m_pattern, m_octaveRange, m_resolution; - Buttons::Button3 m_arpHold; + // SoftKnobs + juce::ComboBox m_softknobFunc1, m_softknobFunc2, m_softknobName1, m_softknobName2; - //SoftKnobs - juce::ComboBox m_softknobFunc1, m_softknobFunc2, m_softknobName1, m_softknobName2; + // PatchSettings + juce::Slider m_patchVolume, m_panning, m_outputBalance, m_transpose; + juce::ComboBox m_keyMode, m_secondaryOutput; + juce::ComboBox m_bendUp, m_bendDown, m_bendScale, m_smoothMode, m_cat1, m_cat2; - //PatchSettings - juce::Slider m_patchVolume, m_panning, m_outputBalance, m_transpose; - juce::ComboBox m_keyMode, m_secondaryOutput; - juce::ComboBox m_bendUp, m_bendDown, m_bendScale, m_smoothMode, m_cat1, m_cat2; - - std::unique_ptr<juce::Drawable> m_background; -}; + std::unique_ptr<juce::Drawable> m_background; + }; +} // namespace Trancy +\ No newline at end of file diff --git a/source/jucePlugin/ui2/Virus_Panel5_PatchBrowser.cpp b/source/jucePlugin/ui2/Virus_Panel5_PatchBrowser.cpp @@ -5,680 +5,685 @@ #include <juce_gui_extra/juce_gui_extra.h> #include <juce_cryptography/juce_cryptography.h> #include "VirusEditor.h" - -using namespace juce; -using namespace virusLib; - -float fBrowserScaleFactor = 2.0f; - -const Array<String> categories = {"", "Lead", "Bass", "Pad", "Decay", "Pluck", - "Acid", "Classic", "Arpeggiator", "Effects", "Drums", "Percussion", - "Input", "Vocoder", "Favourite 1", "Favourite 2", "Favourite 3"}; - -PatchBrowser::PatchBrowser(VirusParameterBinding & _parameterBinding, AudioPluginAudioProcessor &_processorRef) : - m_parameterBinding(_parameterBinding), m_properties(_processorRef.getController().getConfig()), - m_controller(_processorRef.getController()), - m_patchList("Patch browser"), - m_fileFilter("*.syx;*.mid;*.midi", "*", "virus patch dumps"), - m_bankList(FileBrowserComponent::openMode | FileBrowserComponent::canSelectFiles, File::getSpecialLocation(File::SpecialLocationType::currentApplicationFile), &m_fileFilter, NULL), - m_search("Search Box") +class VirusParameterBinding; +namespace Trancy { - setupBackground(*this, m_background, BinaryData::panel_5_png, BinaryData::panel_5_pngSize); - - m_bankList.setLookAndFeel(&m_landf); - - //PatchBrowser - m_bankList.setBounds(0, 185/fBrowserScaleFactor , 1030/fBrowserScaleFactor , 810/fBrowserScaleFactor ); - auto bankDir = m_properties->getValue("virus_bank_dir", ""); - if (bankDir != "" && File(bankDir).isDirectory()) - { - m_bankList.setRoot(bankDir); - } - - setBounds(0, 0, kPanelWidth, kPanelHeight); - - //PatchList - m_patchList.setBounds(1049/fBrowserScaleFactor , 50/fBrowserScaleFactor , 1010/fBrowserScaleFactor , 870/fBrowserScaleFactor ); - - m_patchList.getHeader().addColumn("#", ColumnsPatch::INDEX, 32); - m_patchList.getHeader().addColumn("Name", ColumnsPatch::NAME, 130); - m_patchList.getHeader().addColumn("Category1", ColumnsPatch::CAT1, 84); - m_patchList.getHeader().addColumn("Category2", ColumnsPatch::CAT2, 84); - m_patchList.getHeader().addColumn("Arp", ColumnsPatch::ARP, 32); - m_patchList.getHeader().addColumn("Uni", ColumnsPatch::UNI, 32); - m_patchList.getHeader().addColumn("ST+-", ColumnsPatch::ST, 32); - m_patchList.getHeader().addColumn("Ver", ColumnsPatch::VER, 32); - - addAndMakeVisible(m_patchList); - - m_bankList.setTransform(AffineTransform::scale(fBrowserScaleFactor)); - m_patchList.setTransform(AffineTransform::scale(fBrowserScaleFactor)); - - m_bankList.addListener(this); - m_patchList.setModel(this); - - //Search - m_search.setTransform(AffineTransform::scale(fBrowserScaleFactor)); - m_search.setSize(m_patchList.getWidth(), 20); - m_search.setColour(TextEditor::textColourId, Colours::white); - - m_search.setTopLeftPosition(m_patchList.getBounds().getBottomLeft().translated(0, 8)); - - m_search.onTextChange = [this] { - m_filteredPatches.clear(); - for(auto patch : m_patches) { - const auto searchValue = m_search.getText(); - if (searchValue.isEmpty()) { - m_filteredPatches.add(patch); - } - else if(patch.name.containsIgnoreCase(searchValue)) { - if (patch.name!="") - m_filteredPatches.add(patch); - } - } - m_patchList.updateContent(); - m_patchList.deselectAllRows(); - m_patchList.repaint(); - }; - m_search.setTextToShowWhenEmpty("search...", Colours::grey); - addAndMakeVisible(m_search); - - //Show Options Buttons/Cmb - addAndMakeVisible(m_SavePreset); - addAndMakeVisible(m_ROMBankSelect); - addAndMakeVisible(m_bankList); - - m_ROMBankSelect.setBounds(510 - 961 / 2, 78 - 51 / 2, 961, 51); - for (int i=1; i<=m_controller.getBankCount();i++) + + using namespace juce; + using namespace virusLib; + + float fBrowserScaleFactor = 2.0f; + + const Array<String> categories = {"", "Lead", "Bass", "Pad", "Decay", "Pluck", + "Acid", "Classic", "Arpeggiator", "Effects", "Drums", "Percussion", + "Input", "Vocoder", "Favourite 1", "Favourite 2", "Favourite 3"}; + + PatchBrowser::PatchBrowser(::VirusParameterBinding &_parameterBinding, AudioPluginAudioProcessor &_processorRef) : + m_parameterBinding(_parameterBinding), m_properties(_processorRef.getController().getConfig()), + m_controller(_processorRef.getController()), m_patchList("Patch browser"), + m_fileFilter("*.syx;*.mid;*.midi", "*", "virus patch dumps"), + m_bankList(FileBrowserComponent::openMode | FileBrowserComponent::canSelectFiles, + File::getSpecialLocation(File::SpecialLocationType::currentApplicationFile), &m_fileFilter, NULL), + m_search("Search Box") { - m_ROMBankSelect.addItem("BANK: " + getCurrentPartBankStr((virusLib::BankNumber)i),i+1); - } - - m_ROMBankSelect.onChange = [this]() - { - m_LastBankRomNoUsed = m_ROMBankSelect.getSelectedItemIndex()+1; - LoadBankNr(m_LastBankRomNoUsed); - m_bIsFileMode = false; - m_search.setText("", true); - getParentComponent()->postCommandMessage(VirusEditor::Commands::SelectFirstPatch); - getParentComponent()->postCommandMessage(VirusEditor::Commands::UpdateParts); - SaveSettings(); - }; - - m_SavePreset.setBounds(2197 - m_SavePreset.kWidth / 2, 72 - m_SavePreset.kHeight / 2, m_SavePreset.kWidth, m_SavePreset.kHeight); - m_SavePreset.onClick = [this]() { savePreset(); }; -} - -PatchBrowser::~PatchBrowser() -{ - setLookAndFeel(nullptr); - m_bankList.setLookAndFeel(nullptr); -} - -void PatchBrowser::IntiPatches() -{ - //Read Last Patch used from config file - m_bIsFileMode = m_properties->getBoolValue("is_file_used", false); - m_LastBankRomNoUsed = m_properties->getIntValue("last_bank_rom_no_used", 1); - m_LastFileUsed = m_properties->getValue("last_file_used", ""); + setupBackground(*this, m_background, BinaryData::panel_5_png, BinaryData::panel_5_pngSize); + + m_bankList.setLookAndFeel(&m_landf); + + // PatchBrowser + m_bankList.setBounds(0, 185 / fBrowserScaleFactor, 1030 / fBrowserScaleFactor, 810 / fBrowserScaleFactor); + auto bankDir = m_properties->getValue("virus_bank_dir", ""); + if (bankDir != "" && File(bankDir).isDirectory()) + { + m_bankList.setRoot(bankDir); + } + + setBounds(0, 0, kPanelWidth, kPanelHeight); + + // PatchList + m_patchList.setBounds(1049 / fBrowserScaleFactor, 50 / fBrowserScaleFactor, 1010 / fBrowserScaleFactor, + 870 / fBrowserScaleFactor); + + m_patchList.getHeader().addColumn("#", ColumnsPatch::INDEX, 32); + m_patchList.getHeader().addColumn("Name", ColumnsPatch::NAME, 130); + m_patchList.getHeader().addColumn("Category1", ColumnsPatch::CAT1, 84); + m_patchList.getHeader().addColumn("Category2", ColumnsPatch::CAT2, 84); + m_patchList.getHeader().addColumn("Arp", ColumnsPatch::ARP, 32); + m_patchList.getHeader().addColumn("Uni", ColumnsPatch::UNI, 32); + m_patchList.getHeader().addColumn("ST+-", ColumnsPatch::ST, 32); + m_patchList.getHeader().addColumn("Ver", ColumnsPatch::VER, 32); + + addAndMakeVisible(m_patchList); + + m_bankList.setTransform(AffineTransform::scale(fBrowserScaleFactor)); + m_patchList.setTransform(AffineTransform::scale(fBrowserScaleFactor)); + + m_bankList.addListener(this); + m_patchList.setModel(this); + + // Search + m_search.setTransform(AffineTransform::scale(fBrowserScaleFactor)); + m_search.setSize(m_patchList.getWidth(), 20); + m_search.setColour(TextEditor::textColourId, Colours::white); + + m_search.setTopLeftPosition(m_patchList.getBounds().getBottomLeft().translated(0, 8)); + + m_search.onTextChange = [this] { + m_filteredPatches.clear(); + for (auto patch : m_patches) + { + const auto searchValue = m_search.getText(); + if (searchValue.isEmpty()) + { + m_filteredPatches.add(patch); + } + else if (patch.name.containsIgnoreCase(searchValue)) + { + if (patch.name != "") + m_filteredPatches.add(patch); + } + } + m_patchList.updateContent(); + m_patchList.deselectAllRows(); + m_patchList.repaint(); + }; + m_search.setTextToShowWhenEmpty("search...", Colours::grey); + addAndMakeVisible(m_search); + + // Show Options Buttons/Cmb + addAndMakeVisible(m_SavePreset); + addAndMakeVisible(m_ROMBankSelect); + addAndMakeVisible(m_bankList); + + m_ROMBankSelect.setBounds(510 - 961 / 2, 78 - 51 / 2, 961, 51); + for (int i = 1; i <= m_controller.getBankCount(); i++) + { + m_ROMBankSelect.addItem("BANK: " + getCurrentPartBankStr((virusLib::BankNumber)i), i + 1); + } + + m_ROMBankSelect.onChange = [this]() { + m_LastBankRomNoUsed = m_ROMBankSelect.getSelectedItemIndex() + 1; + LoadBankNr(m_LastBankRomNoUsed); + m_bIsFileMode = false; + m_search.setText("", true); + getParentComponent()->postCommandMessage(VirusEditor::Commands::SelectFirstPatch); + getParentComponent()->postCommandMessage(VirusEditor::Commands::UpdateParts); + SaveSettings(); + }; + + m_SavePreset.setBounds(2197 - m_SavePreset.kWidth / 2, 72 - m_SavePreset.kHeight / 2, m_SavePreset.kWidth, + m_SavePreset.kHeight); + m_SavePreset.onClick = [this]() { savePreset(); }; + } + + PatchBrowser::~PatchBrowser() + { + setLookAndFeel(nullptr); + m_bankList.setLookAndFeel(nullptr); + } - if(!m_bIsFileMode) + void PatchBrowser::IntiPatches() { - m_controller.setCurrentPartPreset(0,(virusLib::BankNumber)(m_LastBankRomNoUsed),0); - m_ROMBankSelect.setSelectedItemIndex(m_LastBankRomNoUsed-1, dontSendNotification); - LoadBankNr(m_LastBankRomNoUsed); - m_search.setText("", true); - - } - else - { - m_bankList.setFileName(m_LastFileUsed); - m_bankList.selectionChanged(); - const File &file(m_LastFileUsed); - LoadPatchesFromFile(file); - } -} - -void PatchBrowser::SaveSettings() -{ - m_properties->setValue("last_file_used", m_LastFileUsed); - m_properties->setValue("is_file_used", m_bIsFileMode); - m_properties->setValue("last_bank_rom_no_used", m_LastBankRomNoUsed); - m_properties->save(); -} + // Read Last Patch used from config file + m_bIsFileMode = m_properties->getBoolValue("is_file_used", false); + m_LastBankRomNoUsed = m_properties->getIntValue("last_bank_rom_no_used", 1); + m_LastFileUsed = m_properties->getValue("last_file_used", ""); + + if (!m_bIsFileMode) + { + m_controller.setCurrentPartPreset(0, (virusLib::BankNumber)(m_LastBankRomNoUsed), 0); + m_ROMBankSelect.setSelectedItemIndex(m_LastBankRomNoUsed - 1, dontSendNotification); + LoadBankNr(m_LastBankRomNoUsed); + m_search.setText("", true); + } + else + { + m_bankList.setFileName(m_LastFileUsed); + m_bankList.selectionChanged(); + const File &file(m_LastFileUsed); + LoadPatchesFromFile(file); + } + } + + void PatchBrowser::SaveSettings() + { + m_properties->setValue("last_file_used", m_LastFileUsed); + m_properties->setValue("is_file_used", m_bIsFileMode); + m_properties->setValue("last_bank_rom_no_used", m_LastBankRomNoUsed); + m_properties->save(); + } -String PatchBrowser::GetLastPatchSelected() -{ - return m_LastPatchSelected; -} + String PatchBrowser::GetLastPatchSelected() { return m_LastPatchSelected; } -TableListBox* PatchBrowser::GetTablePatchList() -{ - return &m_patchList; -} + TableListBox *PatchBrowser::GetTablePatchList() { return &m_patchList; } -String PatchBrowser::GetSelectBankNum() -{ - return getCurrentPartBankStr((virusLib::BankNumber)m_LastBankRomNoUsed); -} + String PatchBrowser::GetSelectBankNum() { return getCurrentPartBankStr((virusLib::BankNumber)m_LastBankRomNoUsed); } + bool PatchBrowser::GetIsFileMode() { return m_bIsFileMode; } + void PatchBrowser::selectionChanged() {} -bool PatchBrowser::GetIsFileMode() -{ - return m_bIsFileMode; -} + void PatchBrowser::LoadBankNr(int iBankNo) + { + StringArray patches = m_controller.getSinglePresetNames((virusLib::BankNumber)(iBankNo)); + m_patches.clear(); + + for (int i = 0; i < 128; i++) + { + Patch patch; + patch.progNumber = i; + // data.copyTo(patch.data, 267*index + 9, 256); + patch.name = patches.strings[i]; + patch.category1 = 0; + patch.category2 = 0; + patch.unison = 0; + patch.transpose = 0; + patch.model = VirusModel::A; + m_patches.add(patch); + } + + m_filteredPatches.clear(); + for (auto patch : m_patches) + { + const auto searchValue = m_search.getText(); + if (searchValue.isEmpty()) + { + m_filteredPatches.add(patch); + } + else if (patch.name.containsIgnoreCase(searchValue)) + { + m_filteredPatches.add(patch); + } + } + m_patchList.updateContent(); + m_patchList.deselectAllRows(); + m_patchList.repaint(); + } + + + int PatchBrowser::loadBankFile(const File &file, const int _startIndex = 0, const bool dedupe = false) + { + auto ext = file.getFileExtension().toLowerCase(); + auto path = file.getParentDirectory().getFullPathName(); + int loadedCount = 0; + int index = _startIndex; + if (ext == ".syx") + { + MemoryBlock data; + if (!file.loadFileAsData(data)) + { + return 0; + } + for (auto it = data.begin(); it != data.end(); it += 267) + { + if ((uint8_t)*it == (uint8_t)0xf0 && (uint8_t) * (it + 1) == (uint8_t)0x00 && + (uint8_t) * (it + 2) == (uint8_t)0x20 && (uint8_t) * (it + 3) == (uint8_t)0x33 && + (uint8_t) * (it + 4) == (uint8_t)0x01 && (uint8_t) * (it + 6) == (uint8_t)virusLib::DUMP_SINGLE) + { + Patch patch; + patch.progNumber = index; + data.copyTo(patch.data, 267 * index + 9, 256); + patch.name = parseAsciiText(patch.data, 128 + 112); + patch.category1 = patch.data[251]; + patch.category2 = patch.data[252]; + patch.unison = patch.data[97]; + patch.transpose = patch.data[93]; + if ((uint8_t) * (it + 266) != (uint8_t)0xf7 && (uint8_t) * (it + 266) != (uint8_t)0xf8) + { + patch.model = VirusModel::TI; + } + else + { + patch.model = guessVersion(patch.data); + } + auto md5 = MD5(it + 9 + 17, 256 - 17 - 3).toHexString(); + if (!dedupe || !m_checksums.contains(md5)) + { + m_checksums.set(md5, true); + m_patches.add(patch); + index++; + } + } + } + } + else if (ext == ".mid" || ext == ".midi") + { + MemoryBlock data; + if (!file.loadFileAsData(data)) + { + return 0; + } + + const uint8_t *ptr = (uint8_t *)data.getData(); + const auto end = ptr + data.getSize(); + + for (auto it = ptr; it < end; it += 1) + { + if ((uint8_t)*it == (uint8_t)0xf0 && + (it + 267) < end) // we don't check for sysex eof so we can load TI banks + { + if ((uint8_t) * (it + 1) == (uint8_t)0x00 && (uint8_t) * (it + 2) == 0x20 && + (uint8_t) * (it + 3) == 0x33 && (uint8_t) * (it + 4) == 0x01 && + (uint8_t) * (it + 6) == virusLib::DUMP_SINGLE) + { + auto syx = Virus::SysEx(it, it + 267); + syx[7] = 0x01; // force to bank a + syx[266] = 0xf7; + + Patch patch; + patch.progNumber = index; + std::copy(syx.begin() + 9, syx.end() - 2, patch.data); + patch.name = parseAsciiText(patch.data, 128 + 112); + patch.category1 = patch.data[251]; + patch.category2 = patch.data[252]; + patch.unison = patch.data[97]; + patch.transpose = patch.data[93]; + if ((uint8_t) * (it + 266) != (uint8_t)0xf7 && (uint8_t) * (it + 266) != (uint8_t)0xf8) + { + patch.model = VirusModel::TI; + } + else + { + patch.model = guessVersion(patch.data); + } + auto md5 = MD5(it + 9 + 17, 256 - 17 - 3).toHexString(); + if (!dedupe || !m_checksums.contains(md5)) + { + m_checksums.set(md5, true); + m_patches.add(patch); + index++; + } + + it += 266; + } + else if ((uint8_t) * (it + 3) == 0x00 // some midi files have two bytes after the 0xf0 + && (uint8_t) * (it + 4) == 0x20 && (uint8_t) * (it + 5) == 0x33 && + (uint8_t) * (it + 6) == 0x01 && (uint8_t) * (it + 8) == virusLib::DUMP_SINGLE) + { + auto syx = Virus::SysEx(); + syx.push_back(0xf0); + for (auto i = it + 3; i < it + 3 + 266; i++) + { + syx.push_back((uint8_t)*i); + } + syx[7] = 0x01; // force to bank a + syx[266] = 0xf7; + + Patch patch; + std::memcpy(patch.data, syx.data() + 9, 256); + patch.progNumber = index; + patch.name = parseAsciiText(patch.data, 128 + 112); + patch.category1 = patch.data[251]; + patch.category2 = patch.data[252]; + patch.unison = patch.data[97]; + patch.transpose = patch.data[93]; + if ((uint8_t) * (it + 2 + 266) != (uint8_t)0xf7 && (uint8_t) * (it + 2 + 266) != (uint8_t)0xf8) + { + patch.model = VirusModel::TI; + } + else + { + patch.model = guessVersion(patch.data); + } + auto md5 = MD5(it + 2 + 9 + 17, 256 - 17 - 3).toHexString(); + if (!dedupe || !m_checksums.contains(md5)) + { + m_checksums.set(md5, true); + m_patches.add(patch); + index++; + } + loadedCount++; + + it += 266; + } + } + } + } + return index; + } + + void PatchBrowser::fileClicked(const File &file, const MouseEvent &e) + { + auto ext = file.getFileExtension().toLowerCase(); + auto path = file.getParentDirectory().getFullPathName(); + + // Show popup only on directory + if (file.isDirectory() && e.mods.isRightButtonDown()) + { + auto p = PopupMenu(); + p.addItem("Add directory contents to patch list", [this, file]() { + m_patches.clear(); + m_checksums.clear(); + int lastIndex = 0; + for (auto f : RangedDirectoryIterator(file, false, "*.syx;*.mid;*.midi", File::findFiles)) + { + lastIndex = loadBankFile(f.getFile(), lastIndex, true); + } + m_filteredPatches.clear(); + for (auto patch : m_patches) + { + const auto searchValue = m_search.getText(); + if (searchValue.isEmpty()) + { + m_filteredPatches.add(patch); + } + else if (patch.name.containsIgnoreCase(searchValue)) + { + m_filteredPatches.add(patch); + } + } + m_patchList.updateContent(); + m_patchList.deselectAllRows(); + m_patchList.repaint(); + }); + p.showMenu(PopupMenu::Options()); + + return; + } + + m_properties->setValue("virus_bank_dir", path); + + if (file.existsAsFile() && ext == ".syx" || ext == ".midi" || ext == ".mid") + { + LoadPatchesFromFile(file); + m_LastFileUsed = file.getFullPathName(); + } + m_bIsFileMode = true; + m_search.setText("", true); + m_ROMBankSelect.setText("", true); + SaveSettings(); + getParentComponent()->postCommandMessage(VirusEditor::Commands::SelectFirstPatch); + getParentComponent()->postCommandMessage(VirusEditor::Commands::UpdateParts); + } + + void PatchBrowser::LoadPatchesFromFile(const File &file) + { + m_patches.clear(); + loadBankFile(file); + m_filteredPatches.clear(); + for (auto patch : m_patches) + { + const auto searchValue = m_search.getText(); + if (searchValue.isEmpty()) + { + m_filteredPatches.add(patch); + } + else if (patch.name.containsIgnoreCase(searchValue)) + { + m_filteredPatches.add(patch); + } + } + m_patchList.updateContent(); + m_patchList.deselectAllRows(); + m_patchList.repaint(); + } + + + void PatchBrowser::fileDoubleClicked(const File &file) {} + + void PatchBrowser::browserRootChanged(const File &newRoot) {} + + int PatchBrowser::getNumRows() { return m_filteredPatches.size(); } + + void PatchBrowser::paintRowBackground(Graphics &g, int rowNumber, int width, int height, bool rowIsSelected) + { + auto alternateColour = getLookAndFeel() + .findColour(ListBox::backgroundColourId) + .interpolatedWith(getLookAndFeel().findColour(ListBox::textColourId), 0.03f); + if (rowIsSelected) + g.fillAll(Colours::lightblue); + else if (rowNumber % 2) + g.fillAll(alternateColour); + } + + void PatchBrowser::paintCell(Graphics &g, int rowNumber, int columnId, int width, int height, bool rowIsSelected) + { + // Banks from file + g.setColour(rowIsSelected ? Colours::darkblue : getLookAndFeel().findColour(ListBox::textColourId)); // [5] + + auto rowElement = m_filteredPatches[rowNumber]; + // auto text = rowElement.name; + String text = ""; + + if (m_bIsFileMode) + { + if (columnId == ColumnsPatch::INDEX) + text = String(rowElement.progNumber + 1); + else if (columnId == ColumnsPatch::NAME) + text = rowElement.name; + else if (columnId == ColumnsPatch::CAT1) + text = categories[rowElement.category1]; + else if (columnId == ColumnsPatch::CAT2) + text = categories[rowElement.category2]; + else if (columnId == ColumnsPatch::ARP) + text = rowElement.data[129] != 0 ? "Y" : " "; + else if (columnId == ColumnsPatch::UNI) + text = rowElement.unison == 0 ? " " : String(rowElement.unison + 1); + else if (columnId == ColumnsPatch::ST) + text = rowElement.transpose != 64 ? String(rowElement.transpose - 64) : " "; + else if (columnId == ColumnsPatch::VER) + { + if (rowElement.model < ModelList.size()) + text = ModelList[rowElement.model]; + } + } + else + { + if (columnId == ColumnsPatch::INDEX) + text = String(rowElement.progNumber + 1); + else if (columnId == ColumnsPatch::NAME) + text = rowElement.name; + } + + g.drawText(text, 2, 0, width - 4, height, Justification::centredLeft, true); // [6] + g.setColour(getLookAndFeel().findColour(ListBox::backgroundColourId)); + g.fillRect(width - 1, 0, 1, height); // [7] + } + + + void PatchBrowser::selectedRowsChanged(int lastRowSelected) + { + auto idx = m_patchList.getSelectedRow(); + if (idx == -1) + { + return; + } + + Component *c; + c = m_patchList.getCellComponent(1, idx); + + if (m_bIsFileMode) + { + uint8_t syxHeader[9] = {0xF0, 0x00, 0x20, 0x33, 0x01, 0x00, 0x10, 0x00, 0x00}; + syxHeader[8] = m_controller.isMultiMode() ? m_controller.getCurrentPart() + : virusLib::ProgramType::SINGLE; // set edit buffer + const uint8_t syxEof = 0xF7; + uint8_t cs = syxHeader[5] + syxHeader[6] + syxHeader[7] + syxHeader[8]; + uint8_t data[256]; + for (int i = 0; i < 256; i++) + { + data[i] = m_filteredPatches[idx].data[i]; + cs += data[i]; + } + cs = cs & 0x7f; + Virus::SysEx syx; + for (auto i : syxHeader) + { + syx.push_back(i); + } + for (auto i : data) + { + syx.push_back(i); + } + syx.push_back(cs); + syx.push_back(syxEof); + m_controller.sendSysEx(syx); // send to edit buffer + m_controller.parseMessage(syx); // update ui + + m_LastPatchSelected = parseAsciiText(data, 128 + 112); + getParentComponent()->postCommandMessage(VirusEditor::Commands::UpdateParts); + } + else + { + m_controller.setCurrentPartPreset(m_controller.getCurrentPart(), (virusLib::BankNumber)m_LastBankRomNoUsed, + m_filteredPatches[idx].progNumber); + getParentComponent()->postCommandMessage(VirusEditor::Commands::UpdateParts); + } + } + + void PatchBrowser::cellDoubleClicked(int rowNumber, int columnId, const MouseEvent &) + { + /* if(m_modeIndex==1) + { + selectedRowsChanged(0); + } + else if (m_modeIndex==0) + { + m_controller.setCurrentPartPreset(m_controller.getCurrentPart(),m_controller.getCurrentPartBank(m_controller.getCurrentPart()),lastRowSelected); + }*/ + } + + + void PatchBrowser::sortOrderChanged(int newSortColumnId, bool isForwards) + { + if (newSortColumnId != 0) + { + PatchBrowser::PatchBrowserSorter sorter(newSortColumnId, isForwards); + m_patches.sort(sorter); + m_patchList.updateContent(); + } + } -void PatchBrowser::selectionChanged() {} -void PatchBrowser::LoadBankNr(int iBankNo) -{ - StringArray patches = m_controller.getSinglePresetNames((virusLib::BankNumber)(iBankNo)); - m_patches.clear(); - - for (int i=0 ; i<128 ; i++) - { - Patch patch; - patch.progNumber = i; - //data.copyTo(patch.data, 267*index + 9, 256); - patch.name = patches.strings[i]; - patch.category1 = 0; - patch.category2 = 0; - patch.unison = 0; - patch.transpose = 0; - patch.model = VirusModel::A; - m_patches.add(patch); - } - - m_filteredPatches.clear(); - for(auto patch : m_patches) { - const auto searchValue = m_search.getText(); - if (searchValue.isEmpty()) { - m_filteredPatches.add(patch); - } - else if(patch.name.containsIgnoreCase(searchValue)) { - m_filteredPatches.add(patch); - } - } - m_patchList.updateContent(); - m_patchList.deselectAllRows(); - m_patchList.repaint(); -} - - -int PatchBrowser::loadBankFile(const File& file, const int _startIndex = 0, const bool dedupe = false) { - auto ext = file.getFileExtension().toLowerCase(); - auto path = file.getParentDirectory().getFullPathName(); - int loadedCount = 0; - int index = _startIndex; - if (ext == ".syx") - { - MemoryBlock data; - if (!file.loadFileAsData(data)) { - return 0; - } - for (auto it = data.begin(); it != data.end(); it += 267) - { - if ((uint8_t)*it == (uint8_t)0xf0 - && (uint8_t)*(it+1) == (uint8_t)0x00 - && (uint8_t)*(it+2) == (uint8_t)0x20 - && (uint8_t)*(it+3) == (uint8_t)0x33 - && (uint8_t)*(it+4) == (uint8_t)0x01 - && (uint8_t)*(it+6) == (uint8_t)virusLib::DUMP_SINGLE) - { - Patch patch; - patch.progNumber = index; - data.copyTo(patch.data, 267*index + 9, 256); - patch.name = parseAsciiText(patch.data, 128 + 112); - patch.category1 = patch.data[251]; - patch.category2 = patch.data[252]; - patch.unison = patch.data[97]; - patch.transpose = patch.data[93]; - if ((uint8_t)*(it + 266) != (uint8_t)0xf7 && (uint8_t)*(it + 266) != (uint8_t)0xf8) { - patch.model = VirusModel::TI; - } - else { - patch.model = guessVersion(patch.data); - } - auto md5 = MD5(it+9 + 17, 256-17-3).toHexString(); - if(!dedupe || !m_checksums.contains(md5)) { - m_checksums.set(md5, true); - m_patches.add(patch); - index++; - } - } - } - } - else if (ext == ".mid" || ext == ".midi") - { - MemoryBlock data; - if (!file.loadFileAsData(data)) - { - return 0; - } - - const uint8_t *ptr = (uint8_t *)data.getData(); - const auto end = ptr + data.getSize(); - - for (auto it = ptr; it < end; it += 1) - { - if ((uint8_t)*it == (uint8_t)0xf0 && (it + 267) < end) // we don't check for sysex eof so we can load TI banks - { - if ((uint8_t) *(it+1) == (uint8_t)0x00 - && (uint8_t)*(it+2) == 0x20 - && (uint8_t)*(it+3) == 0x33 - && (uint8_t)*(it+4) == 0x01 - && (uint8_t)*(it+6) == virusLib::DUMP_SINGLE) - { - auto syx = Virus::SysEx(it, it + 267); - syx[7] = 0x01; // force to bank a - syx[266] = 0xf7; - - Patch patch; - patch.progNumber = index; - std::copy(syx.begin() + 9, syx.end() - 2, patch.data); - patch.name = parseAsciiText(patch.data, 128 + 112); - patch.category1 = patch.data[251]; - patch.category2 = patch.data[252]; - patch.unison = patch.data[97]; - patch.transpose = patch.data[93]; - if ((uint8_t)*(it + 266) != (uint8_t)0xf7 && (uint8_t)*(it + 266) != (uint8_t)0xf8) { - patch.model = VirusModel::TI; - } - else { - patch.model = guessVersion(patch.data); - } - auto md5 = MD5(it+9 + 17, 256-17-3).toHexString(); - if(!dedupe || !m_checksums.contains(md5)) { - m_checksums.set(md5, true); - m_patches.add(patch); - index++; - } - - it += 266; - } - else if((uint8_t)*(it+3) == 0x00 // some midi files have two bytes after the 0xf0 - && (uint8_t)*(it+4) == 0x20 - && (uint8_t)*(it+5) == 0x33 - && (uint8_t)*(it+6) == 0x01 - && (uint8_t)*(it+8) == virusLib::DUMP_SINGLE) - { - auto syx = Virus::SysEx(); - syx.push_back(0xf0); - for (auto i = it + 3; i < it + 3 + 266; i++) - { - syx.push_back((uint8_t)*i); - } - syx[7] = 0x01; // force to bank a - syx[266] = 0xf7; - - Patch patch; - std::memcpy(patch.data, syx.data()+9, 256); - patch.progNumber = index; - patch.name = parseAsciiText(patch.data, 128 + 112); - patch.category1 = patch.data[251]; - patch.category2 = patch.data[252]; - patch.unison = patch.data[97]; - patch.transpose = patch.data[93]; - if ((uint8_t)*(it + 2 + 266) != (uint8_t)0xf7 && (uint8_t)*(it + 2 + 266) != (uint8_t)0xf8) { - patch.model = VirusModel::TI; - } - else { - patch.model = guessVersion(patch.data); - } - auto md5 = MD5(it+2+9 + 17, 256-17-3).toHexString(); - if(!dedupe || !m_checksums.contains(md5)) { - m_checksums.set(md5, true); - m_patches.add(patch); - index++; - } - loadedCount++; - - it += 266; - } - } - } - } - return index; -} - -void PatchBrowser::fileClicked(const File &file, const MouseEvent &e) -{ - auto ext = file.getFileExtension().toLowerCase(); - auto path = file.getParentDirectory().getFullPathName(); - - //Show popup only on directory - if (file.isDirectory() && e.mods.isRightButtonDown()) { - auto p = PopupMenu(); - p.addItem("Add directory contents to patch list", [this, file]() { - m_patches.clear(); - m_checksums.clear(); - int lastIndex = 0; - for (auto f : RangedDirectoryIterator(file, false, "*.syx;*.mid;*.midi", File::findFiles)) { - lastIndex = loadBankFile(f.getFile(), lastIndex, true); - } - m_filteredPatches.clear(); - for(auto patch : m_patches) { - const auto searchValue = m_search.getText(); - if (searchValue.isEmpty()) { - m_filteredPatches.add(patch); - } - else if(patch.name.containsIgnoreCase(searchValue)) { - m_filteredPatches.add(patch); - } - } - m_patchList.updateContent(); - m_patchList.deselectAllRows(); - m_patchList.repaint(); - }); - p.showMenu(PopupMenu::Options()); - - return; - } - - m_properties->setValue("virus_bank_dir", path); - - if(file.existsAsFile() && ext == ".syx" || ext == ".midi" || ext == ".mid") { - LoadPatchesFromFile(file); - m_LastFileUsed = file.getFullPathName(); - } - m_bIsFileMode = true; - m_search.setText("", true); - m_ROMBankSelect.setText("",true); - SaveSettings(); - getParentComponent()->postCommandMessage(VirusEditor::Commands::SelectFirstPatch); - getParentComponent()->postCommandMessage(VirusEditor::Commands::UpdateParts); -} - -void PatchBrowser::LoadPatchesFromFile(const File &file) -{ - m_patches.clear(); - loadBankFile(file); - m_filteredPatches.clear(); - for(auto patch : m_patches) { - const auto searchValue = m_search.getText(); - if (searchValue.isEmpty()) { - m_filteredPatches.add(patch); - } - else if(patch.name.containsIgnoreCase(searchValue)) { - m_filteredPatches.add(patch); - } - } - m_patchList.updateContent(); - m_patchList.deselectAllRows(); - m_patchList.repaint(); -} - - -void PatchBrowser::fileDoubleClicked(const File &file) {} - -void PatchBrowser::browserRootChanged(const File &newRoot) {} - -int PatchBrowser::getNumRows() -{ - return m_filteredPatches.size(); -} - -void PatchBrowser::paintRowBackground(Graphics &g, int rowNumber, int width, int height, bool rowIsSelected) -{ - auto alternateColour = getLookAndFeel() - .findColour(ListBox::backgroundColourId) - .interpolatedWith(getLookAndFeel().findColour(ListBox::textColourId), 0.03f); - if (rowIsSelected) - g.fillAll(Colours::lightblue); - else if (rowNumber % 2) - g.fillAll(alternateColour); -} - -void PatchBrowser::paintCell(Graphics &g, int rowNumber, int columnId, int width, int height, bool rowIsSelected) -{ - //Banks from file - g.setColour(rowIsSelected ? Colours::darkblue - : getLookAndFeel().findColour(ListBox::textColourId)); // [5] - - auto rowElement = m_filteredPatches[rowNumber]; - //auto text = rowElement.name; - String text = ""; - - if (m_bIsFileMode) - { - if (columnId == ColumnsPatch::INDEX) - text = String(rowElement.progNumber+1); - else if (columnId == ColumnsPatch::NAME) - text = rowElement.name; - else if (columnId == ColumnsPatch::CAT1) - text = categories[rowElement.category1]; - else if (columnId == ColumnsPatch::CAT2) - text = categories[rowElement.category2]; - else if (columnId == ColumnsPatch::ARP) - text = rowElement.data[129] != 0 ? "Y" : " "; - else if(columnId == ColumnsPatch::UNI) - text = rowElement.unison == 0 ? " " : String(rowElement.unison+1); - else if(columnId == ColumnsPatch::ST) - text = rowElement.transpose != 64 ? String(rowElement.transpose - 64) : " "; - else if (columnId == ColumnsPatch::VER) { - if(rowElement.model < ModelList.size()) - text = ModelList[rowElement.model]; - } - } - else + void PatchBrowser::loadBankFileToRom(const File &file) { - if (columnId == ColumnsPatch::INDEX) - text = String(rowElement.progNumber+1); - else if (columnId == ColumnsPatch::NAME) - text = rowElement.name; - } - - g.drawText(text, 2, 0, width - 4, height, Justification::centredLeft, true); // [6] - g.setColour(getLookAndFeel().findColour(ListBox::backgroundColourId)); - g.fillRect(width - 1, 0, 1, height); // [7] - -} - - -void PatchBrowser::selectedRowsChanged(int lastRowSelected) { - auto idx = m_patchList.getSelectedRow(); - if (idx == -1) { - return; - } - - Component *c; - c = m_patchList.getCellComponent(1,idx); - - if (m_bIsFileMode) - { - uint8_t syxHeader[9] = {0xF0, 0x00, 0x20, 0x33, 0x01, 0x00, 0x10, 0x00, 0x00}; - syxHeader[8] = m_controller.isMultiMode() ? m_controller.getCurrentPart() : virusLib::ProgramType::SINGLE; // set edit buffer - const uint8_t syxEof = 0xF7; - uint8_t cs = syxHeader[5] + syxHeader[6] + syxHeader[7] + syxHeader[8]; - uint8_t data[256]; - for (int i = 0; i < 256; i++) - { - data[i] = m_filteredPatches[idx].data[i]; - cs += data[i]; - } - cs = cs & 0x7f; - Virus::SysEx syx; - for (auto i : syxHeader) - { - syx.push_back(i); - } - for (auto i : data) - { - syx.push_back(i); - } - syx.push_back(cs); - syx.push_back(syxEof); - m_controller.sendSysEx(syx); // send to edit buffer - m_controller.parseMessage(syx); // update ui - - m_LastPatchSelected = parseAsciiText(data, 128 + 112); - getParentComponent()->postCommandMessage(VirusEditor::Commands::UpdateParts); - } - else - { - m_controller.setCurrentPartPreset(m_controller.getCurrentPart(), (virusLib::BankNumber) m_LastBankRomNoUsed, m_filteredPatches[idx].progNumber); - getParentComponent()->postCommandMessage(VirusEditor::Commands::UpdateParts); - } -} - -void PatchBrowser::cellDoubleClicked(int rowNumber, int columnId, const MouseEvent &) -{ - /* if(m_modeIndex==1) - { - selectedRowsChanged(0); - } - else if (m_modeIndex==0) - { - m_controller.setCurrentPartPreset(m_controller.getCurrentPart(),m_controller.getCurrentPartBank(m_controller.getCurrentPart()),lastRowSelected); - }*/ -} + bool sentData = false; + auto sExt = file.getFileExtension().toLowerCase(); + m_previousPath = file.getParentDirectory().getFullPathName(); + ; + MemoryBlock data; + + if (sExt == ".syx") + { + if (!file.loadFileAsData(data)) + { + return; + } + + for (auto it = data.begin(); it != data.end(); it += 267) + { + if ((it + 267) <= data.end()) + { + m_controller.sendSysEx(Virus::SysEx(it, it + 267)); + sentData = true; + } + } + } + else if (sExt == ".mid" || sExt == ".midi") + { + if (!file.loadFileAsData(data)) + { + return; + } + + const uint8_t *ptr = (uint8_t *)data.getData(); + const auto end = ptr + data.getSize(); + + for (auto it = ptr; it < end; it += 1) + { + if ((uint8_t)*it == (uint8_t)0xf0 && (it + 267) < end) + { + if ((uint8_t) * (it + 1) == 0x00 && (uint8_t) * (it + 2) == 0x20 && (uint8_t) * (it + 3) == 0x33 && + (uint8_t) * (it + 4) == 0x01 && (uint8_t) * (it + 6) == virusLib::DUMP_SINGLE) + { + auto syx = Virus::SysEx(it, it + 267); + syx[7] = 0x01; // force to bank a + syx[266] = 0xf7; + + m_controller.sendSysEx(syx); + + it += 266; + } + else if ((uint8_t) * (it + 3) == 0x00 && (uint8_t) * (it + 4) == 0x20 && + (uint8_t) * (it + 5) == 0x33 && (uint8_t) * (it + 6) == 0x01 && + (uint8_t) * (it + 8) == + virusLib::DUMP_SINGLE) // some midi files have two bytes after the 0xf0 + { + auto syx = Virus::SysEx(); + syx.push_back(0xf0); + for (auto i = it + 3; i < it + 3 + 266; i++) + { + syx.push_back((uint8_t)*i); + } + syx[7] = 0x01; // force to bank a + syx[266] = 0xf7; + m_controller.sendSysEx(syx); + it += 266; + } + + sentData = true; + } + } + } + + if (sentData) + { + m_controller.onStateLoaded(); + } + } + + + void PatchBrowser::loadFile() + { + MemoryBlock data; + FileChooser chooser("Choose syx/midi banks to import", + m_previousPath.isEmpty() + ? File::getSpecialLocation(File::currentApplicationFile).getParentDirectory() + : m_previousPath, + "*.syx,*.mid,*.midi", true); + if (!chooser.browseForFileToOpen()) + return; + loadBankFileToRom(chooser.getResult()); + } -void PatchBrowser::sortOrderChanged(int newSortColumnId, bool isForwards) -{ - if (newSortColumnId != 0) - { - PatchBrowser::PatchBrowserSorter sorter (newSortColumnId, isForwards); - m_patches.sort(sorter); - m_patchList.updateContent(); - } -} - - -void PatchBrowser::loadBankFileToRom(const File &file) -{ - bool sentData = false; - auto sExt = file.getFileExtension().toLowerCase(); - m_previousPath = file.getParentDirectory().getFullPathName();; - MemoryBlock data; - - if (sExt == ".syx") - { - if (!file.loadFileAsData(data)) - { - return; - } - - for (auto it = data.begin(); it != data.end(); it += 267) - { - if ((it + 267) <= data.end()) - { - m_controller.sendSysEx(Virus::SysEx(it, it + 267)); - sentData = true; - } - } - } - else if (sExt == ".mid" || sExt == ".midi") - { - if (!file.loadFileAsData(data)) - { - return; - } - - const uint8_t *ptr = (uint8_t *)data.getData(); - const auto end = ptr + data.getSize(); - - for (auto it = ptr; it < end; it += 1) - { - if ((uint8_t)*it == (uint8_t)0xf0 && (it + 267) < end) - { - if ((uint8_t)*(it+1) == 0x00 - && (uint8_t)*(it+2) == 0x20 - && (uint8_t)*(it+3) == 0x33 - && (uint8_t)*(it+4) == 0x01 - && (uint8_t)*(it+6) == virusLib::DUMP_SINGLE) - { - auto syx = Virus::SysEx(it, it + 267); - syx[7] = 0x01; // force to bank a - syx[266] = 0xf7; - - m_controller.sendSysEx(syx); - - it += 266; - } - else if((uint8_t)*(it+3) == 0x00 - && (uint8_t)*(it+4) == 0x20 - && (uint8_t)*(it+5) == 0x33 - && (uint8_t)*(it+6) == 0x01 - && (uint8_t)*(it+8) == virusLib::DUMP_SINGLE)// some midi files have two bytes after the 0xf0 - { - auto syx = Virus::SysEx(); - syx.push_back(0xf0); - for (auto i = it + 3; i < it + 3 + 266; i++) - { - syx.push_back((uint8_t)*i); - } - syx[7] = 0x01; // force to bank a - syx[266] = 0xf7; - m_controller.sendSysEx(syx); - it += 266; - } - - sentData = true; - } - } - } - - if (sentData) - { - m_controller.onStateLoaded(); - } -} - - -void PatchBrowser::loadFile() -{ - MemoryBlock data; - FileChooser chooser( - "Choose syx/midi banks to import", - m_previousPath.isEmpty() - ? File::getSpecialLocation(File::currentApplicationFile).getParentDirectory() - : m_previousPath, - "*.syx,*.mid,*.midi", true); - - if (!chooser.browseForFileToOpen()) - return; - - loadBankFileToRom(chooser.getResult()); -} - -void PatchBrowser::savePreset() { - FileChooser chooser( - "Save preset as syx", - m_previousPath.isEmpty() - ? File::getSpecialLocation(File::currentApplicationFile).getParentDirectory() - : m_previousPath, - "*.syx", true); - - if (!chooser.browseForFileToSave(true)) - return; - - bool sentData = false; - const auto result = chooser.getResult(); - m_previousPath = result.getParentDirectory().getFullPathName(); - const auto ext = result.getFileExtension().toLowerCase(); - - const uint8_t syxHeader[9] = {0xF0, 0x00, 0x20, 0x33, 0x01, 0x00, 0x10, 0x01, 0x00}; - const uint8_t syxEof[1] = {0xF7}; - uint8_t cs = syxHeader[5] + syxHeader[6] + syxHeader[7] + syxHeader[8]; - uint8_t data[256]; - for (int i = 0; i < 256; i++) - { - auto param = m_controller.getParamValue(m_controller.getCurrentPart(), i < 128 ? 0 : 1, i % 128); - - data[i] = param ? (int)param->getValue() : 0; - cs += data[i]; - } - cs = cs & 0x7f; - - result.deleteFile(); - result.create(); - result.appendData(syxHeader, 9); - result.appendData(data, 256); - result.appendData(&cs, 1); - result.appendData(syxEof, 1); -} + void PatchBrowser::savePreset() + { + FileChooser chooser("Save preset as syx", + m_previousPath.isEmpty() + ? File::getSpecialLocation(File::currentApplicationFile).getParentDirectory() + : m_previousPath, + "*.syx", true); + + if (!chooser.browseForFileToSave(true)) + return; + + bool sentData = false; + const auto result = chooser.getResult(); + m_previousPath = result.getParentDirectory().getFullPathName(); + const auto ext = result.getFileExtension().toLowerCase(); + + const uint8_t syxHeader[9] = {0xF0, 0x00, 0x20, 0x33, 0x01, 0x00, 0x10, 0x01, 0x00}; + const uint8_t syxEof[1] = {0xF7}; + uint8_t cs = syxHeader[5] + syxHeader[6] + syxHeader[7] + syxHeader[8]; + uint8_t data[256]; + for (int i = 0; i < 256; i++) + { + auto param = m_controller.getParamValue(m_controller.getCurrentPart(), i < 128 ? 0 : 1, i % 128); + + data[i] = param ? (int)param->getValue() : 0; + cs += data[i]; + } + cs = cs & 0x7f; + + result.deleteFile(); + result.create(); + result.appendData(syxHeader, 9); + result.appendData(data, 256); + result.appendData(&cs, 1); + result.appendData(syxEof, 1); + } +} // namespace Trancy +\ No newline at end of file diff --git a/source/jucePlugin/ui2/Virus_Panel5_PatchBrowser.h b/source/jucePlugin/ui2/Virus_Panel5_PatchBrowser.h @@ -4,152 +4,165 @@ #include "Virus_Buttons.h" #include <juce_gui_extra/juce_gui_extra.h> #include "../VirusController.h" - -const juce::Array<juce::String> ModelList = {"A","B","C","TI"}; - -struct Patch +class VirusParameterBinding; +namespace Trancy { - int progNumber; - juce::String name; - uint8_t category1; - uint8_t category2; - uint8_t data[256]; - virusLib::VirusModel model; - uint8_t unison; - uint8_t transpose; -}; - - -class PatchBrowser : public juce::Component, juce::FileBrowserListener, juce::TableListBoxModel -{ - -public: - PatchBrowser(VirusParameterBinding &_parameterBinding, AudioPluginAudioProcessor &_processorRef); - ~PatchBrowser(); - void loadFile(); - void loadBankFileToRom(const juce::File &file); - void savePreset(); - bool GetIsFileMode(); - juce::String GetSelectBankNum(); - juce::String GetLastPatchSelected(); - juce::TableListBox* GetTablePatchList(); - - void IntiPatches(); -private: - - Virus::LookAndFeelPatchBrowser m_landf; - - VirusParameterBinding &m_parameterBinding; - Virus::Controller& m_controller; - - template <typename T> juce::String parseAsciiText(const T &msg, const int start) const - { - char text[Virus::Controller::kNameLength + 1]; - text[Virus::Controller::kNameLength] = 0; // termination - for (auto pos = 0; pos < Virus::Controller::kNameLength; ++pos) - text[pos] = msg[start + pos]; - return juce::String(text); - } - - juce::WildcardFileFilter m_fileFilter; - juce::FileBrowserComponent m_bankList; - - juce::TextEditor m_search; - juce::Array<Patch> m_patches; - juce::Array<Patch> m_filteredPatches; - juce::PropertiesFile *m_properties; - juce::HashMap<juce::String, bool> m_checksums; - int loadBankFile(const juce::File &file, const int _startIndex, const bool dedupe); - // Inherited via FileBrowserListener - Buttons::OptionButtonSavePreset m_SavePreset; - - void LoadBankNr(int iBankNo); - void SaveSettings(); - void LoadPatchesFromFile(const juce::File &file); - - juce::ComboBox m_ROMBankSelect; - juce::String m_previousPath; - juce::String m_LastFileUsed; - juce::TableListBox m_patchList; - juce::String m_LastPatchSelected; - - int m_LastBankRomNoUsed; - - bool m_bIsFileMode; - - // Inherited via FileBrowserListener - void selectionChanged() override; - void fileClicked(const juce::File &file, const juce::MouseEvent &e) override; - void fileDoubleClicked(const juce::File &file) override; - void browserRootChanged(const juce::File &newRoot) override; - - // Inherited via TableListBoxModel - virtual int getNumRows() override; - virtual void paintRowBackground(juce::Graphics &, int rowNumber, int width, int height, - bool rowIsSelected) override; - virtual void paintCell(juce::Graphics &, int rowNumber, int columnId, int width, int height, - bool rowIsSelected) override; - - virtual void selectedRowsChanged(int lastRowSelected) override; - virtual void cellDoubleClicked (int rowNumber, int columnId, const juce::MouseEvent &) override; - void sortOrderChanged(int newSortColumnId, bool isForwards) override; - class PatchBrowserSorter; - - enum ColumnsPatch { - INDEX = 1, - NAME = 2, - CAT1 = 3, - CAT2 = 4, - ARP = 5, - UNI = 6, - ST = 7, - VER = 8, - }; - - std::unique_ptr<juce::Drawable> m_background; -}; - - -class PatchBrowser::PatchBrowserSorter -{ -public: - PatchBrowserSorter (int attributeToSortBy, bool forwards) - : attributeToSort (attributeToSortBy), - direction (forwards ? 1 : -1) - {} - - int compareElements (Patch first, Patch second) const - { - if(attributeToSort == ColumnsPatch::INDEX) { - return direction * (first.progNumber - second.progNumber); - } - else if (attributeToSort == ColumnsPatch::NAME) { - return direction * first.name.compareIgnoreCase(second.name); - } - else if (attributeToSort == ColumnsPatch::CAT1) { - return direction * (first.category1 - second.category1); - } - else if (attributeToSort == ColumnsPatch::CAT2) { - return direction * (first.category2 - second.category2); - } - else if (attributeToSort == ColumnsPatch::ARP) { - return direction * (first.data[129]- second.data[129]); - } - else if (attributeToSort == ColumnsPatch::UNI) { - return direction * (first.unison - second.unison); - } - else if (attributeToSort == ColumnsPatch::VER) { - return direction * (first.model - second.model); - } - else if (attributeToSort == ColumnsPatch::ST) { - return direction * (first.transpose - second.transpose); - } - return direction * (first.progNumber - second.progNumber); - } - -private: - int attributeToSort; - int direction; -}; - - + using namespace juce; + const juce::Array<juce::String> ModelList = {"A", "B", "C", "TI"}; + + struct Patch + { + int progNumber; + juce::String name; + uint8_t category1; + uint8_t category2; + uint8_t data[256]; + virusLib::VirusModel model; + uint8_t unison; + uint8_t transpose; + }; + + + class PatchBrowser : public juce::Component, juce::FileBrowserListener, juce::TableListBoxModel + { + + public: + PatchBrowser(VirusParameterBinding & _parameterBinding, AudioPluginAudioProcessor &_processorRef); + ~PatchBrowser(); + void loadFile(); + void loadBankFileToRom(const juce::File &file); + void savePreset(); + bool GetIsFileMode(); + juce::String GetSelectBankNum(); + juce::String GetLastPatchSelected(); + juce::TableListBox *GetTablePatchList(); + + void IntiPatches(); + + private: + VirusUI::LookAndFeelPatchBrowser m_landf; + + VirusParameterBinding &m_parameterBinding; + Virus::Controller &m_controller; + + template <typename T> juce::String parseAsciiText(const T &msg, const int start) const + { + char text[Virus::Controller::kNameLength + 1]; + text[Virus::Controller::kNameLength] = 0; // termination + for (auto pos = 0; pos < Virus::Controller::kNameLength; ++pos) + text[pos] = msg[start + pos]; + return juce::String(text); + } + + juce::WildcardFileFilter m_fileFilter; + juce::FileBrowserComponent m_bankList; + + juce::TextEditor m_search; + juce::Array<Patch> m_patches; + juce::Array<Patch> m_filteredPatches; + juce::PropertiesFile *m_properties; + juce::HashMap<juce::String, bool> m_checksums; + int loadBankFile(const juce::File &file, const int _startIndex, const bool dedupe); + // Inherited via FileBrowserListener + Buttons::OptionButtonSavePreset m_SavePreset; + + void LoadBankNr(int iBankNo); + void SaveSettings(); + void LoadPatchesFromFile(const juce::File &file); + + juce::ComboBox m_ROMBankSelect; + juce::String m_previousPath; + juce::String m_LastFileUsed; + juce::TableListBox m_patchList; + juce::String m_LastPatchSelected; + + int m_LastBankRomNoUsed; + + bool m_bIsFileMode; + + // Inherited via FileBrowserListener + void selectionChanged() override; + void fileClicked(const juce::File &file, const juce::MouseEvent &e) override; + void fileDoubleClicked(const juce::File &file) override; + void browserRootChanged(const juce::File &newRoot) override; + + // Inherited via TableListBoxModel + virtual int getNumRows() override; + virtual void paintRowBackground(juce::Graphics &, int rowNumber, int width, int height, + bool rowIsSelected) override; + virtual void paintCell(juce::Graphics &, int rowNumber, int columnId, int width, int height, + bool rowIsSelected) override; + + virtual void selectedRowsChanged(int lastRowSelected) override; + virtual void cellDoubleClicked(int rowNumber, int columnId, const juce::MouseEvent &) override; + void sortOrderChanged(int newSortColumnId, bool isForwards) override; + class PatchBrowserSorter; + + enum ColumnsPatch + { + INDEX = 1, + NAME = 2, + CAT1 = 3, + CAT2 = 4, + ARP = 5, + UNI = 6, + ST = 7, + VER = 8, + }; + + std::unique_ptr<juce::Drawable> m_background; + }; + + + class PatchBrowser::PatchBrowserSorter + { + public: + PatchBrowserSorter(int attributeToSortBy, bool forwards) : + attributeToSort(attributeToSortBy), direction(forwards ? 1 : -1) + { + } + + int compareElements(Patch first, Patch second) const + { + if (attributeToSort == ColumnsPatch::INDEX) + { + return direction * (first.progNumber - second.progNumber); + } + else if (attributeToSort == ColumnsPatch::NAME) + { + return direction * first.name.compareIgnoreCase(second.name); + } + else if (attributeToSort == ColumnsPatch::CAT1) + { + return direction * (first.category1 - second.category1); + } + else if (attributeToSort == ColumnsPatch::CAT2) + { + return direction * (first.category2 - second.category2); + } + else if (attributeToSort == ColumnsPatch::ARP) + { + return direction * (first.data[129] - second.data[129]); + } + else if (attributeToSort == ColumnsPatch::UNI) + { + return direction * (first.unison - second.unison); + } + else if (attributeToSort == ColumnsPatch::VER) + { + return direction * (first.model - second.model); + } + else if (attributeToSort == ColumnsPatch::ST) + { + return direction * (first.transpose - second.transpose); + } + return direction * (first.progNumber - second.progNumber); + } + + private: + int attributeToSort; + int direction; + }; + + +} // namespace Trancy +\ No newline at end of file