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 fd329516a4536371d3b8634e096575646147fe9e
parent 5a637caeec83ab5bc5bd70e9bcad259c3ac60809
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date:   Wed,  5 Jun 2024 23:38:43 +0200

focused parameter does not fight anymore between UI and automation/midi changes, UI is preferred over automation/midi now

Diffstat:
Msource/jucePluginEditorLib/focusedParameter.cpp | 108++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------
Msource/jucePluginEditorLib/focusedParameter.h | 16+++++++++++++++-
2 files changed, 94 insertions(+), 30 deletions(-)

diff --git a/source/jucePluginEditorLib/focusedParameter.cpp b/source/jucePluginEditorLib/focusedParameter.cpp @@ -3,12 +3,45 @@ #include "pluginEditor.h" #include "../jucePluginLib/controller.h" +#include "../jucePluginLib/parameter.h" #include "../jucePluginLib/parameterbinding.h" namespace jucePluginEditorLib { constexpr int g_defaultDisplayTimeout = 1500; // milliseconds + namespace + { + FocusedParameter::Priority getPriority(pluginLib::Parameter::Origin _origin) + { + switch (_origin) + { + case pluginLib::Parameter::Origin::Unknown: + case pluginLib::Parameter::Origin::PresetChange: + case pluginLib::Parameter::Origin::Derived: + default: + return FocusedParameter::Priority::Low; + case pluginLib::Parameter::Origin::Midi: + case pluginLib::Parameter::Origin::HostAutomation: + return FocusedParameter::Priority::Medium; + case pluginLib::Parameter::Origin::Ui: + return FocusedParameter::Priority::High; + } + } + + FocusedParameter::Priority getPriority(const pluginLib::Parameter* _param) + { + if(!_param) + return FocusedParameter::Priority::None; + return getPriority(_param->getChangeOrigin()); + } + + bool operator < (const FocusedParameter::Priority _a, const FocusedParameter::Priority _b) + { + return static_cast<int>(_a) < static_cast<int>(_b); + } + } + FocusedParameter::FocusedParameter(const pluginLib::Controller& _controller, const pluginLib::ParameterBinding& _parameterBinding, const genericUI::Editor& _editor) : m_parameterBinding(_parameterBinding) , m_controller(_controller) @@ -23,7 +56,7 @@ namespace jucePluginEditorLib m_tooltip.reset(new FocusedParameterTooltip(_editor.findComponentT<juce::Label>("FocusedParameterTooltip", false), _editor)); - updateControlLabel(nullptr); + updateControlLabel(nullptr, Priority::None); for (auto& params : m_controller.getExposedParameters()) { @@ -35,7 +68,7 @@ namespace jucePluginEditorLib _param->getChangeOrigin() == pluginLib::Parameter::Origin::Derived) return; if(auto* comp = m_parameterBinding.getBoundComponent(_param)) - updateControlLabel(comp); + updateControlLabel(comp, _param); })}); } } @@ -53,7 +86,7 @@ namespace jucePluginEditorLib auto* component = _event.eventComponent; if(component && component->getProperties().contains("parameter")) - updateControlLabel(component); + updateControlLabel(component, Priority::High); } void FocusedParameter::updateParameter(const std::string& _name, const std::string& _value) @@ -86,13 +119,11 @@ namespace jucePluginEditorLib void FocusedParameter::timerCallback() { - updateControlLabel(nullptr); + updateControlLabel(nullptr, Priority::High); } - void FocusedParameter::updateControlLabel(juce::Component* _component) + void FocusedParameter::updateControlLabel(juce::Component* _component, const Priority _prio) { - stopTimer(); - if(_component) { // combo boxes report the child label as event source, try the parent in this case @@ -100,44 +131,63 @@ namespace jucePluginEditorLib _component = _component->getParentComponent(); } - if(!_component || !_component->getProperties().contains("parameter")) - { - updateParameter({}, {}); - m_tooltip->setVisible(false); - return; - } + const auto* param = getParameterFromComponent(_component); - const auto& props = _component->getProperties(); - const int v = props["parameter"]; + updateControlLabel(_component, param, _prio); + } - const int part = props.contains("part") ? static_cast<int>(props["part"]) : static_cast<int>(m_controller.getCurrentPart()); + void FocusedParameter::updateControlLabel(juce::Component* _component, const pluginLib::Parameter* _param, Priority _priority) + { + if(_priority < m_currentPriority) + return; - const auto* p = m_controller.getParameter(v, static_cast<uint8_t>(part)); + stopTimer(); - // do not show soft knob parameter if the softknob is bound to another parameter - if(p && p->getDescription().isSoftKnob()) - { - const auto* softKnob = m_controller.getSoftknob(p); - if(softKnob && softKnob->isBound()) - p = softKnob->getTargetParameter(); - } - if(!p) + if(!_param || !_component) { + m_currentPriority = Priority::None; updateParameter({}, {}); m_tooltip->setVisible(false); return; } - const auto value = p->getText(p->getValue(), 0).toStdString(); - - const auto& desc = p->getDescription(); + const auto value = _param->getText(_param->getValue(), 0).toStdString(); - updateParameter(desc.displayName, value); + updateParameter(_param->getDescription().displayName, value); m_tooltip->initialize(_component, value); const auto tooltipTime = m_tooltip && m_tooltip->isValid() ? m_tooltip->getTooltipDisplayTime() : g_defaultDisplayTimeout; startTimer(tooltipTime == 0 ? g_defaultDisplayTimeout : static_cast<int>(tooltipTime)); + + m_currentPriority = _priority; + } + + void FocusedParameter::updateControlLabel(juce::Component* _component, const pluginLib::Parameter* _param) + { + return updateControlLabel(_component, _param, getPriority(_param)); + } + + const pluginLib::Parameter* FocusedParameter::getParameterFromComponent(juce::Component* _component) const + { + if(!_component || !_component->getProperties().contains("parameter")) + return nullptr; + + const auto& props = _component->getProperties(); + const int paramIdx = props["parameter"]; + + const int part = props.contains("part") ? static_cast<int>(props["part"]) : static_cast<int>(m_controller.getCurrentPart()); + + const auto* param = m_controller.getParameter(paramIdx, static_cast<uint8_t>(part)); + + // do not show soft knob parameter if the softknob is bound to another parameter + if(param && param->getDescription().isSoftKnob()) + { + const auto* softKnob = m_controller.getSoftknob(param); + if(softKnob && softKnob->isBound()) + return softKnob->getTargetParameter(); + } + return param; } } diff --git a/source/jucePluginEditorLib/focusedParameter.h b/source/jucePluginEditorLib/focusedParameter.h @@ -28,6 +28,14 @@ namespace jucePluginEditorLib class FocusedParameter : juce::Timer { public: + enum class Priority + { + None, + Low, + Medium, + High + }; + FocusedParameter(const pluginLib::Controller& _controller, const pluginLib::ParameterBinding& _parameterBinding, const genericUI::Editor& _editor); ~FocusedParameter() override; @@ -37,14 +45,20 @@ namespace jucePluginEditorLib private: void timerCallback() override; - void updateControlLabel(juce::Component* _component); + void updateControlLabel(juce::Component* _component, Priority _prio); + void updateControlLabel(juce::Component* _component, const pluginLib::Parameter* _param); + void updateControlLabel(juce::Component* _component, const pluginLib::Parameter* _param, Priority _priority); + const pluginLib::Parameter* getParameterFromComponent(juce::Component* _component) const; const pluginLib::ParameterBinding& m_parameterBinding; const pluginLib::Controller& m_controller; juce::Label* m_focusedParameterName = nullptr; juce::Label* m_focusedParameterValue = nullptr; + std::unique_ptr<FocusedParameterTooltip> m_tooltip; + std::map<pluginLib::Parameter*, pluginLib::ParameterListener> m_boundParameters; + Priority m_currentPriority = Priority::None; }; }