diff --git a/extras/Introjucer/Builds/CodeBlocks/The Introjucer.cbp b/extras/Introjucer/Builds/CodeBlocks/The Introjucer.cbp index 0b88494203..4b99ceb029 100644 --- a/extras/Introjucer/Builds/CodeBlocks/The Introjucer.cbp +++ b/extras/Introjucer/Builds/CodeBlocks/The Introjucer.cbp @@ -21,6 +21,8 @@ + + @@ -55,6 +57,7 @@ + diff --git a/extras/audio plugin demo/Source/PluginEditor.cpp b/extras/audio plugin demo/Source/PluginEditor.cpp index c850c884f8..ab9edc0e5e 100644 --- a/extras/audio plugin demo/Source/PluginEditor.cpp +++ b/extras/audio plugin demo/Source/PluginEditor.cpp @@ -12,9 +12,9 @@ #include "PluginEditor.h" //============================================================================== -JuceDemoPluginAudioProcessorEditor::JuceDemoPluginAudioProcessorEditor (JuceDemoPluginAudioProcessor* ownerFilter) - : AudioProcessorEditor (ownerFilter), - midiKeyboard (ownerFilter->keyboardState, MidiKeyboardComponent::horizontalKeyboard), +JuceDemoPluginAudioProcessorEditor::JuceDemoPluginAudioProcessorEditor (JuceDemoPluginAudioProcessor& owner) + : AudioProcessorEditor (owner), + midiKeyboard (owner.keyboardState, MidiKeyboardComponent::horizontalKeyboard), infoLabel (String::empty), gainLabel ("", "Throughput level:"), delayLabel ("", "Delay:"), @@ -51,8 +51,8 @@ JuceDemoPluginAudioProcessorEditor::JuceDemoPluginAudioProcessorEditor (JuceDemo resizeLimits.setSizeLimits (150, 150, 800, 300); // set our component's initial size to be the last one that was stored in the filter's settings - setSize (ownerFilter->lastUIWidth, - ownerFilter->lastUIHeight); + setSize (owner.lastUIWidth, + owner.lastUIHeight); startTimer (50); } @@ -80,23 +80,23 @@ void JuceDemoPluginAudioProcessorEditor::resized() resizer->setBounds (getWidth() - 16, getHeight() - 16, 16, 16); - getProcessor()->lastUIWidth = getWidth(); - getProcessor()->lastUIHeight = getHeight(); + getProcessor().lastUIWidth = getWidth(); + getProcessor().lastUIHeight = getHeight(); } //============================================================================== // This timer periodically checks whether any of the filter's parameters have changed... void JuceDemoPluginAudioProcessorEditor::timerCallback() { - JuceDemoPluginAudioProcessor* ourProcessor = getProcessor(); + JuceDemoPluginAudioProcessor& ourProcessor = getProcessor(); - AudioPlayHead::CurrentPositionInfo newPos (ourProcessor->lastPosInfo); + AudioPlayHead::CurrentPositionInfo newPos (ourProcessor.lastPosInfo); if (lastDisplayedPosition != newPos) displayPositionInfo (newPos); - gainSlider.setValue (ourProcessor->gain, dontSendNotification); - delaySlider.setValue (ourProcessor->delay, dontSendNotification); + gainSlider.setValue (ourProcessor.gain, dontSendNotification); + delaySlider.setValue (ourProcessor.delay, dontSendNotification); } // This is our Slider::Listener callback, when the user drags a slider. @@ -107,13 +107,13 @@ void JuceDemoPluginAudioProcessorEditor::sliderValueChanged (Slider* slider) // It's vital to use setParameterNotifyingHost to change any parameters that are automatable // by the host, rather than just modifying them directly, otherwise the host won't know // that they've changed. - getProcessor()->setParameterNotifyingHost (JuceDemoPluginAudioProcessor::gainParam, - (float) gainSlider.getValue()); + getProcessor().setParameterNotifyingHost (JuceDemoPluginAudioProcessor::gainParam, + (float) gainSlider.getValue()); } else if (slider == &delaySlider) { - getProcessor()->setParameterNotifyingHost (JuceDemoPluginAudioProcessor::delayParam, - (float) delaySlider.getValue()); + getProcessor().setParameterNotifyingHost (JuceDemoPluginAudioProcessor::delayParam, + (float) delaySlider.getValue()); } } diff --git a/extras/audio plugin demo/Source/PluginEditor.h b/extras/audio plugin demo/Source/PluginEditor.h index 03808b9997..6ac62702ad 100644 --- a/extras/audio plugin demo/Source/PluginEditor.h +++ b/extras/audio plugin demo/Source/PluginEditor.h @@ -23,7 +23,7 @@ class JuceDemoPluginAudioProcessorEditor : public AudioProcessorEditor, public Timer { public: - JuceDemoPluginAudioProcessorEditor (JuceDemoPluginAudioProcessor* ownerFilter); + JuceDemoPluginAudioProcessorEditor (JuceDemoPluginAudioProcessor&); ~JuceDemoPluginAudioProcessorEditor(); //============================================================================== @@ -41,9 +41,9 @@ private: AudioPlayHead::CurrentPositionInfo lastDisplayedPosition; - JuceDemoPluginAudioProcessor* getProcessor() const + JuceDemoPluginAudioProcessor& getProcessor() const { - return static_cast (getAudioProcessor()); + return static_cast (processor); } void displayPositionInfo (const AudioPlayHead::CurrentPositionInfo& pos); diff --git a/extras/audio plugin demo/Source/PluginProcessor.cpp b/extras/audio plugin demo/Source/PluginProcessor.cpp index 39a633e835..61781c2dda 100644 --- a/extras/audio plugin demo/Source/PluginProcessor.cpp +++ b/extras/audio plugin demo/Source/PluginProcessor.cpp @@ -21,8 +21,8 @@ class SineWaveSound : public SynthesiserSound public: SineWaveSound() {} - bool appliesToNote (const int /*midiNoteNumber*/) { return true; } - bool appliesToChannel (const int /*midiChannel*/) { return true; } + bool appliesToNote (const int /*midiNoteNumber*/) override { return true; } + bool appliesToChannel (const int /*midiChannel*/) override { return true; } }; //============================================================================== @@ -36,13 +36,13 @@ public: { } - bool canPlaySound (SynthesiserSound* sound) + bool canPlaySound (SynthesiserSound* sound) override { return dynamic_cast (sound) != 0; } void startNote (int midiNoteNumber, float velocity, - SynthesiserSound* /*sound*/, int /*currentPitchWheelPosition*/) + SynthesiserSound* /*sound*/, int /*currentPitchWheelPosition*/) override { currentAngle = 0.0; level = velocity * 0.15; @@ -54,7 +54,7 @@ public: angleDelta = cyclesPerSample * 2.0 * double_Pi; } - void stopNote (bool allowTailOff) + void stopNote (bool allowTailOff) override { if (allowTailOff) { @@ -74,17 +74,17 @@ public: } } - void pitchWheelMoved (int /*newValue*/) + void pitchWheelMoved (int /*newValue*/) override { // can't be bothered implementing this for the demo! } - void controllerMoved (int /*controllerNumber*/, int /*newValue*/) + void controllerMoved (int /*controllerNumber*/, int /*newValue*/) override { // not interested in controllers in this case. } - void renderNextBlock (AudioSampleBuffer& outputBuffer, int startSample, int numSamples) + void renderNextBlock (AudioSampleBuffer& outputBuffer, int startSample, int numSamples) override { if (angleDelta != 0.0) { @@ -303,7 +303,7 @@ void JuceDemoPluginAudioProcessor::processBlock (AudioSampleBuffer& buffer, Midi //============================================================================== AudioProcessorEditor* JuceDemoPluginAudioProcessor::createEditor() { - return new JuceDemoPluginAudioProcessorEditor (this); + return new JuceDemoPluginAudioProcessorEditor (*this); } //============================================================================== diff --git a/modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp b/modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp index f290d6b853..aa23881d7f 100644 --- a/modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp +++ b/modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp @@ -177,6 +177,20 @@ struct AAXClasses return nullptr; } + static Colour getColourFromHighlightEnum (AAX_EHighlightColor colour) noexcept + { + switch (colour) + { + case AAX_eHighlightColor_Red: return Colours::red; + case AAX_eHighlightColor_Blue: return Colours::blue; + case AAX_eHighlightColor_Green: return Colours::green; + case AAX_eHighlightColor_Yellow: return Colours::yellow; + default: jassertfalse; break; + } + + return Colours::black; + } + //============================================================================== class JuceAAX_Processor; @@ -306,27 +320,40 @@ struct AAXClasses return AAX_ERROR_NULL_OBJECT; } - AAX_Result ParameterUpdated (AAX_CParamID /*paramID*/) override + AAX_Result ParameterUpdated (AAX_CParamID) override { return AAX_SUCCESS; } - AAX_Result SetControlHighlightInfo (AAX_CParamID /*paramID*/, AAX_CBoolean /*isHighlighted*/, AAX_EHighlightColor) override + AAX_Result SetControlHighlightInfo (AAX_CParamID paramID, AAX_CBoolean isHighlighted, AAX_EHighlightColor colour) override { - return AAX_SUCCESS; + if (component != nullptr && component->pluginEditor != nullptr) + { + AudioProcessorEditor::ParameterControlHighlightInfo info; + info.parameterIndex = getParamIndexFromID (paramID); + info.isHighlighted = isHighlighted; + info.suggestedColour = getColourFromHighlightEnum (colour); + + component->pluginEditor->setControlHighlight (info); + return AAX_SUCCESS; + } + + return AAX_ERROR_NULL_OBJECT; } private: - class ContentWrapperComponent : public juce::Component + struct ContentWrapperComponent : public juce::Component { - public: ContentWrapperComponent (JuceAAX_GUI& gui, AudioProcessor& plugin) : owner (gui) { setOpaque (true); - addAndMakeVisible (pluginEditor = plugin.createEditorIfNeeded()); - setBounds (pluginEditor->getLocalBounds()); setBroughtToFrontOnMouseClick (true); + + addAndMakeVisible (pluginEditor = plugin.createEditorIfNeeded()); + + if (pluginEditor != nullptr) + setBounds (pluginEditor->getLocalBounds()); } ~ContentWrapperComponent() @@ -334,7 +361,7 @@ struct AAXClasses if (pluginEditor != nullptr) { PopupMenu::dismissAllActiveMenus(); - pluginEditor->getAudioProcessor()->editorBeingDeleted (pluginEditor); + pluginEditor->processor.editorBeingDeleted (pluginEditor); } } @@ -356,7 +383,6 @@ struct AAXClasses } } - private: ScopedPointer pluginEditor; JuceAAX_GUI& owner; diff --git a/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp b/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp index 06b485c9ef..85b11f240b 100644 --- a/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp +++ b/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp @@ -458,7 +458,7 @@ private: if (pluginEditor != nullptr) { PopupMenu::dismissAllActiveMenus(); - pluginEditor->getAudioProcessor()->editorBeingDeleted (pluginEditor); + pluginEditor->processor.editorBeingDeleted (pluginEditor); } } diff --git a/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp b/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp index efb75b59b8..e640ca714a 100644 --- a/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp +++ b/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp @@ -1446,7 +1446,7 @@ public: warnOnFailure (view->removed()); warnOnFailure (view->setFrame (nullptr)); - getAudioProcessor()->editorBeingDeleted (this); + processor.editorBeingDeleted (this); #if JUCE_MAC dummyComponent.setView (nullptr); diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.cpp b/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.cpp index a4c9d296b7..72f4c41e46 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.cpp +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.cpp @@ -22,16 +22,21 @@ ============================================================================== */ -AudioProcessorEditor::AudioProcessorEditor (AudioProcessor* const p) - : owner (p) +AudioProcessorEditor::AudioProcessorEditor (AudioProcessor& p) noexcept : processor (p) +{ +} + +AudioProcessorEditor::AudioProcessorEditor (AudioProcessor* p) noexcept : processor (*p) { // the filter must be valid.. - jassert (owner != nullptr); + jassert (p != nullptr); } AudioProcessorEditor::~AudioProcessorEditor() { // if this fails, then the wrapper hasn't called editorBeingDeleted() on the // filter for some reason.. - jassert (owner->getActiveEditor() != this); + jassert (processor.getActiveEditor() != this); } + +void AudioProcessorEditor::setControlHighlight (ParameterControlHighlightInfo) {} diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.h b/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.h index 3c811a254e..8926ae9e9c 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.h +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.h @@ -39,9 +39,11 @@ class JUCE_API AudioProcessorEditor : public Component { protected: //============================================================================== - /** Creates an editor for the specified processor. - */ - AudioProcessorEditor (AudioProcessor* owner); + /** Creates an editor for the specified processor. */ + AudioProcessorEditor (AudioProcessor&) noexcept; + + /** Creates an editor for the specified processor. */ + AudioProcessorEditor (AudioProcessor*) noexcept; public: /** Destructor. */ @@ -49,14 +51,31 @@ public: //============================================================================== - /** Returns a pointer to the processor that this editor represents. */ - AudioProcessor* getAudioProcessor() const noexcept { return owner; } + /** The AudioProcessor that this editor represents. */ + AudioProcessor& processor; + /** Returns a pointer to the processor that this editor represents. + This method is here to support legacy code, but it's easier to just use the + AudioProcessorEditor::processor member variable directly to get this object. + */ + AudioProcessor* getAudioProcessor() const noexcept { return &processor; } -private: //============================================================================== - AudioProcessor* const owner; + /** Used by the setParameterHighlighting() method. */ + struct ParameterControlHighlightInfo + { + int parameterIndex; + bool isHighlighted; + Colour suggestedColour; + }; + + /** Some types of plugin can call this to suggest that the control for a particular + parameter should be highlighted. + Currently only AAX plugins will call this, and implementing it is optional. + */ + virtual void setControlHighlight (ParameterControlHighlightInfo); +private: JUCE_DECLARE_NON_COPYABLE (AudioProcessorEditor) };