DocumentWindow setContentOwned VST


#1

So I have a PluginWindow derived from DocumentWindow and if I add a AudioProcessorEditor to the PluginWindow using:

setContentOwned (editor, true);

Where editor is a AudioProcessorEditor*

The plug-in editor shows up fine at all times… but if I create a simple PluginComponent class:

 class PluginComponent : public Component,
                            public ComponentListener
{
 public:

    PluginComponent (AudioProcessorEditor* pEditor) : m_pEditor (pEditor)
    {
        int iWidth = m_pEditor->getWidth();
        int iHeight = m_pEditor->getHeight();
    
        setSize (iWidth, iHeight);
    
        m_pEditor->setTopLeftPosition (0, 0);
    
        addAndMakeVisible (m_pEditor);

        m_pEditor->addComponentListener (this);
    }

    ~PluginComponent()
    {
        m_pEditor->removeComponentListener (this);
    }

    void componentMovedOrResized (Component& component, bool wasMoved, bool wasResized) override
    {
        if (wasResized && m_pEditor == &component)
            {
            int iWidth = m_pEditor->getWidth();
            int iHeight = m_pEditor->getHeight();
        
            setSize (iWidth, iHeight);
        
            m_pEditor->setTopLeftPosition (0, 0);
            }
    }

    void paint (Graphics& g) override
    {
        g.fillAll (Colours::red);
    }


 private:

    AudioProcessorEditor* m_pEditor = nullptr;

    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PluginComponent);
};

and add the PluginComponent like this:

 setContentOwned (new PluginComponent (editor), true);

It works fine for almost all plug-in manufacturers except one that I’ve tested… in that case the first time the Window is displayed it draws the VST2 AudioProcessorEditor, but if I close and re-open the Window the plug-in area is black.

Stepping though the code I don’t see anything wrong… and if I load a VST3 version of the plug-in it always draws correctly.

Any thoughts on why the VST2 when embedded in a “parent” Component will not repaint (for a particular plug-in)… but when not embedded in another Component paints fine?

Thanks,

Rail


#2

I’m seeing a CVDisplayLink thread when this Manufacturer’s plug-ins are loaded… so that may be a clue??

Rail


#3

Hmmmm that’s really strange. I can’t really see any difference between using your PluginComponent or not. Are you sure that the editor is being properly released when using your PluginComponent? Maybe you are re-creating the editor with the old one still hanging around?


#4

No, that would occur then without the PluginComponent as well… Since it only happens with FabFilter plug-ins… they must be using some OpenGL threading which is using CVDisplayLink… which is causing a problem. I checked the pEditor values in the debugger… and they seemed fine.

I’m looking at creating my plug-in header bar using setMenuBarComponent as a kludge instead… but I don’t see a parameter in setMenuBarComponent to set newMenuBarHeight and it doesn’t get the height from the Component.

Rail


Waves Abbey Road and DocumentWindow issue
#5

This change would be welcome :slight_smile:

void DocumentWindow::setMenuBarComponent (Component* newMenuBarComponent)
{
    menuBarHeight = newMenuBarComponent->getHeight();  //  Added this

    // (call the Component method directly to avoid the assertion in ResizableWindow)
    Component::addAndMakeVisible (menuBar = newMenuBarComponent);

    if (menuBar != nullptr)
        menuBar->setEnabled (isActiveWindow());

    resized();
} 

This allows me to create a Toolbar Component:

class ToolbarComponent : public Component
{
 public:

    ToolbarComponent (AudioProcessor* pProcessor) : m_pProcessor (pProcessor),
                                                m_BypassButton ("B")
    {
        setSize (100, 38);

        m_BypassButton.setBounds (5, 5, 30, 30);

        addAndMakeVisible (m_BypassButton);
    }

    void paint (Graphics& g) override
    {
        g.fillAll (Colours::grey);
    }

 private:

    AudioProcessor* m_pProcessor;

    TextButton      m_BypassButton;

     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ToolbarComponent);
};

Rail


#6

Why don’t you just use void DocumentWindow::setMenuBar (MenuBarModel* newMenuBarModel, const int newMenuBarHeight)?


#7

I didn’t think I could use a custom Component for that using the MenuBarModel… I’ll dig in deeper… This isn’t going to really be a “menu”… but it’ll have a Preset ComboBox, and 4 buttons which I’ll use to interact directly with the AudioProcessor.

Thanks,

Rail


#8

That won’t work for my purpose… but this small change would make sense to me:

void DocumentWindow::setMenuBarComponent (Component* newMenuBarComponent)
{
    if (menuBar == nullptr)
        menuBarHeight = newMenuBarComponent->getHeight();

    // (call the Component method directly to avoid the assertion in ResizableWindow)
    Component::addAndMakeVisible (menuBar = newMenuBarComponent);

    if (menuBar != nullptr)
        menuBar->setEnabled (isActiveWindow());

    resized();
}

Rail


#9

Hmmm, Jules and I don’t really like this suggestion as it’s the parent’s component responsibility to resize the menuBar component. For example, the default menuBar component has a size of zero by default. For example, I would expect the following to work:

documentWindow.setMenuBarComponent (new MenuBarComponent (myMenuBar));

But with your change the menuBarHeight would be zero (as the default height of MenuBarComponent is zero). It might be better to add a default argument to setMenuBarComponent to override the menuBarHeight?


#10

I’d be fine with that :slight_smile:

As I mentioned… this particular use is a bit of a kludge… but I can see being able to set the height for the component would be useful anyway.

Thanks!

Rail