I would like to open their GUIs as they’re loaded. This could be in separate windows or in the window that’s got the slots for the graph.
I’ve also used ProJucer to create a new plugin. I’ve put the new plugin’s files into the tutorial’s files and used ProJucer to add PluginEditor.cpp and PluginEditor.h to the tutorial project.
I’ve changed the PluginEditor.h so the private class member audioProcessor is of type ProcessorBase&. And made ProcessorBase& the expected type for the data passed to the constructor.
In the tutorial code, in the header file, I’ve changed the ProcessorBase class so that the methods hasEditor() and createEditor() are just declarations and then modified main.cpp as follows:
#include "PluginEditor.h"
#include <iostream>
//=======================================================
juce::AudioProcessorEditor* ProcessorBase::createEditor()
{
std::cout "asking for an editor\n";
return new NewProjectAudioProcessorEditor (*this);
}
bool ProcessorBase::hasEditor() const
{ return true; }
In the included header, in the TutorialProcessor class, in the updateGraph() method, under the if (hasChanged), I’ve added slot->getProcessor()->createEditorIfNeeded (); on line 387-ish.
I can tell from my cout that createEditor() is being called and know that the constructor for the editor is running, but no window opens.
If the AudioProcessors you are playing are compiled into the project, as seen in this tutorial, you can add them as child using addAndMakeVisible and set the bounds. However the AudioProcessorEditor may change it’s size by itself, so the usual resized() routine might be different, I haven’t tried.
If it is in a window, it is best to use the ResizeableWindow, which has a bool flag when setting the AudioProcessorEditor as content:
If you show plugin editors, that are not compiled in, the AudioProcessorEditor will take care of wrapping the editor into a HWNDComponent, NSViewComponent or XEmbedComponent.
In file included from ../../Source/Main.cpp:10:
../../Source/AudioProcessorGraphTutorial_01.h: In member function ‘void TutorialProcessor::updateGraph()’:
../../Source/AudioProcessorGraphTutorial_01.h:388:97: error: use of deleted function ‘juce::ResizableWindow::ResizableWindow(const juce::ResizableWindow&)’
388 | leWindow win = ResizableWindow (slot->getProcessor()->getName(), true);
| ^
In file included from /home/celesteh/Documents/code/JUCE/modules/juce_core/system/juce_StandardHeader.h:79,
from /home/celesteh/Documents/code/JUCE/modules/juce_core/juce_core.h:204,
from /home/celesteh/Documents/code/JUCE/modules/juce_audio_basics/juce_audio_basics.h:54,
from ../../JuceLibraryCode/JuceHeader.h:16,
from ../../Source/Main.cpp:9:
/home/celesteh/Documents/code/JUCE/modules/juce_gui_basics/windows/juce_ResizableWindow.h:410:51: note: declared here
410 | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ResizableWindow)
| ^~~~~~~~~~~~~~~
/home/celesteh/Documents/code/JUCE/modules/juce_core/system/juce_PlatformDefs.h:231:5: note: in definition of macro ‘JUCE_DECLARE_NON_COPYABLE’
231 | className (const className&) = delete;\
| ^~~~~~~~~
/home/celesteh/Documents/code/JUCE/modules/juce_gui_basics/windows/juce_ResizableWindow.h:410:5: note: in expansion of macro ‘JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR’
410 | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ResizableWindow)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
make: *** [Makefile:181: build/intermediate/Debug/Main_90ebc5c2.o] Error 1
Yes, this cannot work.
You are trying to create a ResizableWindow on the stack. But it would be deleted when the scope ends.
Instead you need a unique_ptr owned somewhere as member of a class like this:
// member
std::unique_ptr<juce::ResizableWindow> win;
// created like this:
win = std::make_unique<juce::ResizableWindow>(slot->getProcessor()->getName(), true);
win->setContentOwned (slot->getProcessor()->createEditor(), true);
win->addToDesktop (/* flags */);
win->setVisible (true);
Notes:
Don’t use createEditorIfNeeded(), because you take ownership. The IfNeeded might return a pointer to an editor instance, that is already owned somewhere else.
And I am not sure, if updateGraph() is a great place, it sounds it could be called much more often than you think.