Styling the Standalone plugin window?

Is it possible to style the Standalone plugin window? It doesn’t seem like I have access to it inside my editor.

I’m thinking that it should look like a proper OS window as much as possible. Can/should I do that? Or is that something that class should do itself?

Thanks.

PS - One of my testers on Mac asked, “What’s that red cross icon? And shouldn’t it ask if I really want to quit the app?”

https://www.juce.com/doc/classTopLevelWindow#a749fbd5e688ed8c9af3d0d99b21e18c8

1 Like

Thank you.

So I put this in:

AudioProcessorEditor* MyAudioProcessor::createEditor()
{
    editor = new Editor(*this);
    if(wrapperType == wrapperType_Standalone)
    {
        if(TopLevelWindow::getNumTopLevelWindows() == 1)
        {
            TopLevelWindow* w = TopLevelWindow::getTopLevelWindow(0);
            w->setUsingNativeTitleBar(true);
        }
    }
    return editor;
}

While this now uses the native title bar, the Options button/menu is unfortunately now gone.

You can always just roll your own standalone window class - if you look at the default one, it’s only a couple of hundred lines of code, and there’s really nothing clever going on in there. TBH the default one is really just there as a demo or a test-harness, we’d expect anyone who’s shipping a real product to want to build a more custom holder themselves.

Hi Jules,

I checked this out briefly when the change to add a Standalone to the export in ProJucer was added… but there didn’t seem a simple mechanism to change the default class to one of our own in a ProJucer created project.

Rail

3 Likes

I was wondering the same thing…where do I hook into it?

For what it’s worth, it’s probably better to leave the Options button off the gui anyway and make it a Preferences menu item.

2 Likes

Can we hope for more info about this in JUCE 5?

3 Likes

You can define JUCE_USE_CUSTOM_AU3_STANDALONE_APP=1 and then role your own JUCEApplication. See juce_audio_plugin_client_Standalone.cpp:35

3 Likes

Thanks Fabian,

Obviously I missed that.

Cheers,

Rail

We should rename this preprocessor define as it’s no longer only relevant to AUv3.

2 Likes

Hey! I’d like to just override a method or two. Is there a way of doing so?
Seems like when I enable the macro I have to start from scratch?

Sorry, but this doesn’t seem clear.

So to use our own standalone class, we should set JUCE_USE_CUSTOM_AU3_STANDALONE_APP to 1 and then create a class that’s called StandaloneFilterApp?

Ahh thanks for pointing that out. In fact, we broke the functionality of JUCE_USE_CUSTOM_AU3_STANDALONE_APP with JUCE 5.

I’ve now fixed this on develop and also renamed the macro to JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP . Simply define this to 1 in your AppConfig.h (or add it as a custom compiler pre-processor definition) and then use the START_JUCE_APPLICATION macro as you would in a normal standalone app.

1 Like

Sorry @fabian, but I still don’t understand. You say to use the START_JUCE_APPLICATION macro as I normally would, but I’ve never used that macro before nor do I know how to use it.

Just to be clear, I just want to style the standalone app to look as close as possible to a proper OS app, which the generated JUCE code does not do…and shouldn’t it?

Do I need to create a subclass of StandaloneFilterApp or StandaloneFilterWindow or both?

Please, just a little example code here would go a long way. Thank you.

1 Like

There are two approaches here that you could do:

  1. you use the standalone app that JUCE already provides for you. Then you don’t need any macros etc. This is the approach that JUCE’s audio plugin demo uses. If you want different behaviour in your standalone app (compared to your plug-in), you can use:

    PluginHostType::getPluginLoadedAs() == AudioProcessor::wrapperType_Standalone

    For example, you could use this in a parentHierarchyChanged callback in your plug-ins editor to change the window styling of the top-level window.

  1. You write your own standalone app class just the way you would when writing a standalone JUCE app. If you look at any JUCE GUI example project (which isn’t a plugin), there is a START_JUCE_APPLICATION (JUCEHelloWorldApplication) at the very end. So for this option, you subclass JUCEApplication, just as you would when writing a standalone app, and it’s up to you to initialise the device manager and instantiate your AudioProcessor etc. This is obviously much more work, but gives you a lot more flexibility.

To try out option 2) just copy the source files of the HelloWorld project into the JUCE audio plugin demo. Then in the Projucer add the source files (Main.cpp, MainComponent.cpp, MainComponent.h) to the audio demo plugin project and ensure that JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP=1 in Preprocesser definitions. Then just build and run your app. The standalone target will now just show the HelloWorld window. Obviously, for an audio plug-in you would change the HelloWorld code to instantiate your plug-in and editor.

6 Likes

Hi Fabian,

Perhaps you an give me a pointer on what’s the simplest way to have the Standalone allow all the outputs available for the selected driver… for instance SoundFlower 64 has 32 stereo Outputs available… my plug-in has

MyPluginProc:: MyPluginProc() : AudioProcessor (BusesProperties()
                                .withOutput ("Out 1-2",  AudioChannelSet::stereo(), true)
                                .withOutput ("Out 3-4",  AudioChannelSet::stereo(), false)
                                .withOutput ("Out 5-6",  AudioChannelSet::stereo(), false)
                                .withOutput ("Out 7-8",  AudioChannelSet::stereo(), false)
                                .withOutput ("Out 9-10",  AudioChannelSet::stereo(), false)
                                .withOutput ("Out 11-12",  AudioChannelSet::stereo(), false)
                                .withOutput ("Out 13-14",  AudioChannelSet::stereo(), false)
                                .withOutput ("Out 15-16",  AudioChannelSet::stereo(), false)
                                .withOutput ("Out 17-18",  AudioChannelSet::stereo(), false)
                                .withOutput ("Out 19-20", AudioChannelSet::stereo(), false)
                                .withOutput ("Out 21-22", AudioChannelSet::stereo(), false)
                                .withOutput ("Out 23-24", AudioChannelSet::stereo(), false)
                                .withOutput ("Out 25-26", AudioChannelSet::stereo(), false)
                                .withOutput ("Out 27-28", AudioChannelSet::stereo(), false)
                                .withOutput ("Out 29-30", AudioChannelSet::stereo(), false)
                                .withOutput ("Out 31-32", AudioChannelSet::stereo(), false)
                                                             ),
 : 
 {
     if (wrapperType == AudioProcessor::wrapperType_Standalone)
           enableAllBuses();
     :
 }

and

 bool MyPluginProc::isBusesLayoutSupported (const BusesLayout& layouts) const
{
    if (layouts.getMainInputChannels() == 0 && layouts.getMainOutputChannels() == 2)
        return true;

    if (layouts.getMainInputChannels() == 0 && layouts.getMainOutputChannels() == 32)
        return true;

    return false;
}

This is working as a plug-in… and also as Standalone with stereo out.

However, in the Audio Setup you can’t select more than a stereo output (you can change which stereo outputs are used, but you can’t select more than one stereo output at a time).

Any ideas?

It may just be easier to use AudioAppComponent in a fresh GUI App. and load the VST into an AudioProcessorGraph.

Thanks,

Rail

The standalone plugin will only ever use a single bus. So in standalone mode you should only have a single output bus which should be capable of many channels.

Okay - I think it’ll just be easier to roll my own Standalone using AudioAppComponent and loading the VST… I don’t think you have an output bus which can have 32 discrete outputs (unless I’m missing something).

Cheers,

Rail

You can just use discrete channels AudioChannelSet::discreteChannels (X).

Oh, cool… I’ll try that!

Thanks,

Rail