Sub-window for AudioProcessorEditor not showing

I’ve been trying to make a settings window for my AU plugin, accessible through the click of a button. However, despite thoroughly studying the API docs and WindowDemo of the demo runner, nothing shows. I ran it with the Xcode debugger attached to Logic Pro, and the window is being created because the local variable for its pointer is populated as expected. I just can’t get it to show up.

As usual, the code is located at https://github.com/NebuHiiEjamu/CinemixAutomationBridge. I’m most likely missing something or some line of code is out of order.

Yes, you are missing an addToDesktop.

However, best practice is to prefer an overlay component inside your editor.

But at least it’s not modal…

2 Likes

Alright, much appreciated. I’m just trying to get everything to work right now. After that, I’ll start optimising it.

also I’ve found with sub-windows you fall into this crappy situation:

the sub-window will not show in front of the main plugin window in the majority of hosts unless you call setAlwaysOnTop(true) on the window, as the main plugin window has been set “always on top” by the host.
in hosts like Ableton where the default behaviour is to hide the main plugin window when selecting some other track then the sub-window stays visisble
afaict there is no way to be notified when the main plugin window has been hidden in order to hide the sub-window, and leaving it visible is suboptimal behaviour imo.
additionally in every host I tested, because you set always on top, the sub-window is, surprise surprise, always on top, even when the main window has lost focus and had its always on topness (?) removed by the host.

Read:

Rail

2 Likes

So I went back and decided to make the sub-window a component instead, along with making everything in the main window a panel as well, so I can toggle between the two. However, now nothing is showing up. I’m not sure what I’m doing wrong. setBounds (getLocalBounds()) should set the size and position, shouldn’t it?

setBounds (getLocalBounds())
only if you call it on a child, otherwise it’s just setting the bounds it is reading, doing nothing.

panel1.setBounds (getLocalBounds());

:wink:

I mean, I do. I guess I wasn’t clear enough. This is in the editor’s resized() function:

if (prefsPanel && prefsPanel->isVisible()) prefsPanel->setBounds (getLocalBounds());
    else if (mainPanel) mainPanel->setBounds (getLocalBounds());

Ok, I thought so, just ruling out the obvious :slight_smile:

What I tend to do is, to always set the bounds of all possible components, and only switch visibility.
That is, because you are not guaranteed to get a resized() when you switch the other panel visible. In fact, you most likely don’t.

Well, the only time I toggle visibility is in the constructors, and the button onClick lambdas.

well, either you make sure, the bounds are always legit, regardless of visibility (simplest), or you call resized() each time after you toggle visibility inside your lambda (more maintenance)…

Well both panel components have the local bounds of the editor window. Am I missing something?

In the resized() you posted, you only set the bounds, if it’s visible. If you set it later visible, it has still zero bounds… or did I miss something?

So setting visibility resets the bounds?

well, I might have missed something, but the only time resized() is called, when the parent’s bounds are set or changed (in case of an AudioProcessorEditor it’s the setSize() call at the end of the constructor).

When it calls now your resized, I’ll copy here:

void resized() override
{
    if (prefsPanel && prefsPanel->isVisible())     // not executed, since prefsPanel is not visible
        prefsPanel->setBounds (getLocalBounds());
    else if (mainPanel) 
        mainPanel->setBounds (getLocalBounds());
}

once you call in your lambda (I am assuming):

prefsButton.onClick = [&]
{
    prefsPanel->setVisible();  // sets it visible, but still has zero size
};

but if you post your lambdas we can verify/falsify

1 Like

Alright, I see now. However, not sure why the main panel is invisible.

Is the repository up to date? then I can take a look

It is.

Ok, the mistake is to set the size at the beginning, when the panels are both not yet created.
setSize() calls synchronously the resized() callback.
So move the setSize() to the end of the constructor will solve that riddle.

But another note: you are calling delete, which is no longer best practice. Prefer the use of RAII like std::unique_ptr.

AutomationBridgeSettings* prefsPanel

becomes

std::unique_ptr<AutomationBridgeSettings> prefsPanel;

and it is created like:

prefsPanel = std::make_unique<AutomationBridgeSettings> (this);

When the unique_ptr object goes out of scope, by whichever means, it will take care of the proper destruction…

2 Likes

Appreciated. I’ll give that a try.