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 3bb85ffd922ecfdb999fe5a69bef8ff32cd27b53
parent a9d1359285507778aeef241266914dede9a83ce0
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date:   Thu, 18 Apr 2024 23:38:19 +0200

multi mode and save button WIP

Diffstat:
Msource/xtJucePlugin/CMakeLists.txt | 2++
Msource/xtJucePlugin/skins/xtDefault/xtDefault.json | 81+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
Msource/xtJucePlugin/skins/xtDefault/xtDefaultBG.png | 0
Msource/xtJucePlugin/xtEditor.cpp | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msource/xtJucePlugin/xtEditor.h | 17+++++++++++++++++
Asource/xtJucePlugin/xtPartButton.cpp | 23+++++++++++++++++++++++
Asource/xtJucePlugin/xtPartButton.h | 22++++++++++++++++++++++
Asource/xtJucePlugin/xtParts.cpp | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Asource/xtJucePlugin/xtParts.h | 30++++++++++++++++++++++++++++++
9 files changed, 279 insertions(+), 4 deletions(-)

diff --git a/source/xtJucePlugin/CMakeLists.txt b/source/xtJucePlugin/CMakeLists.txt @@ -13,6 +13,8 @@ set(SOURCES xtFrontPanel.cpp xtFrontPanel.h xtFocusedParameter.cpp xtFocusedParameter.h xtLcd.cpp xtLcd.h + xtPartButton.cpp xtPartButton.h + xtParts.cpp xtParts.h xtPatchManager.cpp xtPatchManager.h version.h ) diff --git a/source/xtJucePlugin/skins/xtDefault/xtDefault.json b/source/xtJucePlugin/skins/xtDefault/xtDefault.json @@ -226,7 +226,7 @@ "normalImageOn" : "1", "overImageOn" : "1", "downImageOn" : "1", - "x" : "2320.399", + "x" : "2417.109", "y" : "69.64844", "width" : "128", "height" : "128", @@ -245,7 +245,7 @@ "normalImageOn" : "1", "overImageOn" : "1", "downImageOn" : "1", - "x" : "2522.399", + "x" : "2604.909", "y" : "69.64844", "width" : "128", "height" : "128", @@ -264,7 +264,7 @@ "normalImageOn" : "1", "overImageOn" : "1", "downImageOn" : "1", - "x" : "2724.399", + "x" : "2792.709", "y" : "69.64844", "width" : "128", "height" : "128", @@ -283,7 +283,7 @@ "normalImageOn" : "1", "overImageOn" : "1", "downImageOn" : "1", - "x" : "3026.109", + "x" : "3040.309", "y" : "69.64844", "width" : "128", "height" : "128", @@ -315,6 +315,7 @@ "name" : "PartButtonSmall", "button" : { "isToggle" : "1", + "radioGroupId" : "96", "normalImage" : "0", "overImage" : "0", "downImage" : "1", @@ -334,6 +335,7 @@ "name" : "PartLedSmall", "button" : { "isToggle" : "1", + "radioGroupId" : "97", "normalImage" : "0", "overImage" : "0", "downImage" : "0", @@ -353,6 +355,7 @@ "name" : "PartButtonSmall", "button" : { "isToggle" : "1", + "radioGroupId" : "96", "normalImage" : "0", "overImage" : "0", "downImage" : "1", @@ -372,6 +375,7 @@ "name" : "PartLedSmall", "button" : { "isToggle" : "1", + "radioGroupId" : "97", "normalImage" : "0", "overImage" : "0", "downImage" : "0", @@ -391,6 +395,7 @@ "name" : "PartButtonSmall", "button" : { "isToggle" : "1", + "radioGroupId" : "96", "normalImage" : "0", "overImage" : "0", "downImage" : "1", @@ -410,6 +415,7 @@ "name" : "PartLedSmall", "button" : { "isToggle" : "1", + "radioGroupId" : "97", "normalImage" : "0", "overImage" : "0", "downImage" : "0", @@ -429,6 +435,7 @@ "name" : "PartButtonSmall", "button" : { "isToggle" : "1", + "radioGroupId" : "96", "normalImage" : "0", "overImage" : "0", "downImage" : "1", @@ -448,6 +455,7 @@ "name" : "PartLedSmall", "button" : { "isToggle" : "1", + "radioGroupId" : "97", "normalImage" : "0", "overImage" : "0", "downImage" : "0", @@ -467,6 +475,7 @@ "name" : "PartButtonSmall", "button" : { "isToggle" : "1", + "radioGroupId" : "96", "normalImage" : "0", "overImage" : "0", "downImage" : "1", @@ -486,6 +495,7 @@ "name" : "PartLedSmall", "button" : { "isToggle" : "1", + "radioGroupId" : "97", "normalImage" : "0", "overImage" : "0", "downImage" : "0", @@ -505,6 +515,7 @@ "name" : "PartButtonSmall", "button" : { "isToggle" : "1", + "radioGroupId" : "96", "normalImage" : "0", "overImage" : "0", "downImage" : "1", @@ -524,6 +535,7 @@ "name" : "PartLedSmall", "button" : { "isToggle" : "1", + "radioGroupId" : "97", "normalImage" : "0", "overImage" : "0", "downImage" : "0", @@ -543,6 +555,7 @@ "name" : "PartButtonSmall", "button" : { "isToggle" : "1", + "radioGroupId" : "96", "normalImage" : "0", "overImage" : "0", "downImage" : "1", @@ -562,6 +575,7 @@ "name" : "PartLedSmall", "button" : { "isToggle" : "1", + "radioGroupId" : "97", "normalImage" : "0", "overImage" : "0", "downImage" : "0", @@ -581,6 +595,7 @@ "name" : "PartButtonSmall", "button" : { "isToggle" : "1", + "radioGroupId" : "96", "normalImage" : "0", "overImage" : "0", "downImage" : "1", @@ -600,6 +615,7 @@ "name" : "PartLedSmall", "button" : { "isToggle" : "1", + "radioGroupId" : "97", "normalImage" : "0", "overImage" : "0", "downImage" : "0", @@ -616,6 +632,63 @@ } }, { + "name" : "MultiModeButton", + "button" : { + "isToggle" : "1", + "normalImage" : "0", + "overImage" : "0", + "downImage" : "1", + "normalImageOn" : "1", + "overImageOn" : "1", + "downImageOn" : "1", + "x" : "2159", + "y" : "69.65002", + "width" : "128", + "height" : "128", + "texture" : "xtknob", + "tileSizeX" : "128", + "tileSizeY" : "128" + } + }, + { + "name" : "MultiModeLED", + "button" : { + "isToggle" : "1", + "normalImage" : "0", + "overImage" : "0", + "downImage" : "0", + "normalImageOn" : "1", + "overImageOn" : "1", + "downImageOn" : "1", + "x" : "2271", + "y" : "53.65002", + "width" : "32", + "height" : "32", + "texture" : "led", + "tileSizeX" : "128", + "tileSizeY" : "128" + } + }, + { + "name" : "SaveButton", + "button" : { + "isToggle" : "1", + "normalImage" : "0", + "overImage" : "0", + "downImage" : "1", + "normalImageOn" : "1", + "overImageOn" : "1", + "downImageOn" : "1", + "x" : "2159", + "y" : "298.17", + "width" : "128", + "height" : "128", + "texture" : "xtknob", + "tileSizeX" : "128", + "tileSizeY" : "128" + } + }, + { "name" : "pagePatchManager", "image" : { "x" : "35.99988", diff --git a/source/xtJucePlugin/skins/xtDefault/xtDefaultBG.png b/source/xtJucePlugin/skins/xtDefault/xtDefaultBG.png Binary files differ. diff --git a/source/xtJucePlugin/xtEditor.cpp b/source/xtJucePlugin/xtEditor.cpp @@ -7,12 +7,15 @@ #include "xtFocusedParameter.h" #include "xtFrontPanel.h" #include "xtPatchManager.h" +#include "../jucePluginLib/parameterbinding.h" namespace xtJucePlugin { Editor::Editor(jucePluginEditorLib::Processor& _processor, pluginLib::ParameterBinding& _binding, std::string _skinFolder, const std::string& _jsonFilename) : jucePluginEditorLib::Editor(_processor, _binding, std::move(_skinFolder)) , m_controller(dynamic_cast<Controller&>(_processor.getController())) + , m_parameterBinding(_binding) + , m_playModeChangeListener(m_controller.onPlayModeChanged) { create(_jsonFilename); @@ -20,9 +23,12 @@ namespace xtJucePlugin m_frontPanel.reset(new FrontPanel(*this, m_controller)); + m_parts.reset(new Parts(*this)); + addMouseListener(this, true); { + // Init Patch Manager const auto container = findComponent("ContainerPatchManager"); constexpr auto scale = 1.3f; const float x = static_cast<float>(container->getX()); @@ -38,6 +44,31 @@ namespace xtJucePlugin setPatchManager(new PatchManager(*this, container, dir)); } + + m_btMultiMode = findComponentT<juce::Button>("MultiModeButton"); + m_ledMultiMode = findComponentT<juce::Button>("MultiModeLED"); + + m_btMultiMode->onClick = [this] + { + m_controller.setPlayMode(m_btMultiMode->getToggleState()); + }; + + m_playModeChangeListener = [this](const bool& isMultiMode) + { + m_btMultiMode->setToggleState(isMultiMode, juce::dontSendNotification); + m_ledMultiMode->setToggleState(isMultiMode, juce::dontSendNotification); + }; + + m_btSave = findComponentT<juce::DrawableButton>("SaveButton"); + m_btSave->onClick = [this] + { + juce::PopupMenu menu; + + const auto countAdded = getPatchManager()->createSaveMenuEntries(menu, getPatchManager()->getCurrentPart()); + + if(countAdded) + menu.showMenuAsync(juce::PopupMenu::Options()); + }; } Editor::~Editor() @@ -81,6 +112,30 @@ namespace xtJucePlugin return m_frontPanel->getLcd(); } + Parts& Editor::getParts() const + { + assert(m_parts); + return *m_parts; + } + + genericUI::Button<juce::DrawableButton>* Editor::createJuceComponent( + genericUI::Button<juce::DrawableButton>* _button, genericUI::UiObject& _object, const std::string& _name, + juce::DrawableButton::ButtonStyle _buttonStyle) + { + if(_name == "PartButtonSmall") + return new PartButton(*this, _name, _buttonStyle); + + return jucePluginEditorLib::Editor::createJuceComponent(_button, _object, _name, _buttonStyle); + } + + void Editor::setCurrentPart(const uint8_t _part) + { + m_controller.setCurrentPart(_part); + m_parameterBinding.setPart(_part); + + jucePluginEditorLib::Editor::setCurrentPart(_part); + } + void Editor::mouseEnter(const juce::MouseEvent& _event) { m_focusedParameter->onMouseEnter(_event); diff --git a/source/xtJucePlugin/xtEditor.h b/source/xtJucePlugin/xtEditor.h @@ -1,7 +1,11 @@ #pragma once +#include "xtParts.h" + #include "../jucePluginEditorLib/pluginEditor.h" +#include "../jucePluginLib/event.h" + class XtLcd; class Controller; @@ -40,12 +44,25 @@ namespace xtJucePlugin Controller& getXtController() const { return m_controller; } XtLcd* getLcd() const; + Parts& getParts() const; + + genericUI::Button<juce::DrawableButton>* createJuceComponent(genericUI::Button<juce::DrawableButton>*, genericUI::UiObject& _object, const std::string& _name, juce::DrawableButton::ButtonStyle) override; + + void setCurrentPart(uint8_t _part) override; private: void mouseEnter(const juce::MouseEvent& _event) override; Controller& m_controller; + pluginLib::ParameterBinding& m_parameterBinding; std::unique_ptr<FocusedParameter> m_focusedParameter; std::unique_ptr<FrontPanel> m_frontPanel; + std::unique_ptr<Parts> m_parts; + + pluginLib::EventListener<bool> m_playModeChangeListener; + + juce::Button* m_btMultiMode = nullptr; + juce::Button* m_ledMultiMode = nullptr; + juce::Button* m_btSave = nullptr; }; } diff --git a/source/xtJucePlugin/xtPartButton.cpp b/source/xtJucePlugin/xtPartButton.cpp @@ -0,0 +1,23 @@ +#include "xtPartButton.h" + +#include "xtEditor.h" + +namespace xtJucePlugin +{ + PartButton::PartButton(Editor& _editor, const std::string& _name, ButtonStyle _buttonStyle) + : jucePluginEditorLib::PartButton<DrawableButton>(_editor, _name, _buttonStyle) + , m_editor(_editor) + { + } + + void PartButton::setPart(const uint8_t _part) + { + m_part = _part; + } + + void PartButton::onClick() + { + if(!m_editor.getParts().selectPart(m_part)) + setToggleState(false, juce::dontSendNotification); + } +} diff --git a/source/xtJucePlugin/xtPartButton.h b/source/xtJucePlugin/xtPartButton.h @@ -0,0 +1,22 @@ +#pragma once + +#include "../jucePluginEditorLib/partbutton.h" + +namespace xtJucePlugin +{ + class Editor; + + class PartButton : public jucePluginEditorLib::PartButton<juce::DrawableButton> + { + public: + PartButton(Editor& _editor, const std::string& _name, ButtonStyle _buttonStyle); + + void setPart(uint8_t _part); + + void onClick() override; + + private: + Editor& m_editor; + uint8_t m_part; + }; +} diff --git a/source/xtJucePlugin/xtParts.cpp b/source/xtJucePlugin/xtParts.cpp @@ -0,0 +1,53 @@ +#include "xtParts.h" + +#include "xtController.h" +#include "xtEditor.h" + +namespace xtJucePlugin +{ + Parts::Parts(Editor& _editor) : m_editor(_editor) + { + std::vector<PartButton*> buttons; + std::vector<juce::Button*> leds; + + _editor.findComponents<PartButton>(buttons, "PartButtonSmall", 8); + _editor.findComponents<juce::Button>(leds, "PartLedSmall", 8); + + for(size_t i=0; i<m_parts.size(); ++i) + { + auto& part = m_parts[i]; + part.m_button = buttons[i]; + part.m_led = leds[i]; + + part.m_button->setPart(static_cast<uint8_t>(i)); + } + + updateUi(); + } + + bool Parts::selectPart(const uint8_t _part) + { + if(_part >= m_parts.size()) + return false; + if(_part > 0 && !m_editor.getXtController().isMultiMode()) + return false; + m_editor.setCurrentPart(_part); + + updateUi(); + + return true; + } + + void Parts::updateUi() + { + const auto currentPart = m_editor.getXtController().getCurrentPart(); + + for(size_t i=0; i<m_parts.size(); ++i) + { + auto& part = m_parts[i]; + + part.m_led->setToggleState(i == currentPart, juce::dontSendNotification); + part.m_button->setToggleState(i == currentPart, juce::dontSendNotification); + } + } +} diff --git a/source/xtJucePlugin/xtParts.h b/source/xtJucePlugin/xtParts.h @@ -0,0 +1,29 @@ +#pragma once + +#include "../jucePluginEditorLib/partbutton.h" + +#include "xtPartButton.h" + +namespace xtJucePlugin +{ + class Parts + { + public: + Parts(Editor& _editor); + + bool selectPart(uint8_t _part); + + private: + void updateUi(); + + Editor& m_editor; + + struct Part + { + PartButton* m_button = nullptr; + juce::Button* m_led = nullptr; + }; + + std::array<Part,8> m_parts; + }; +} +\ No newline at end of file