Updated guide to create your own standalone plugin window

This has been an ongoing issue for quite a few years and I thought some of you might find this useful, especially with the changes to JUCE over time.

This will allow you to have your standalone app use the native titlebar (instead of JUCE’s) and also give you a better place to style that window to your liking without modifying the JUCE library code. You’ll also be able to open the AudioMidi dialog from your own UI element.

Honestly, it really shouldn’t be this complicated. I really don’t know why something like this wouldn’t be the default.

  • From inside your JUCE modules folder, make copies of juce_StandaloneFilterWindow.h and juce_audio_plugin_client_Standalone.cpp and put them in your source tree and project.
  • Rename them CustomStandaloneFilterWindow.h and CustomStandalone.cpp respectively.

  • In the Projucer, in your project settings, add JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP=1 to Preprocessor definitions.

  • In CustomStandalone.cpp:
    – Near the top of the file, find #if ! JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP and remove the !
    – Right below that, comment out
    #include <juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h>
    and add
    #include "CustomStandaloneFilterWindow.h"
    – Change the name of the class StandaloneFilterApp to CustomStandaloneFilterApp.
    – Change the class constructor name from StandaloneFilterApp() to CustomStandaloneFilterApp().
    – Near the bottom of the file, comment out extern juce::JUCEApplicationBase* juce_CreateApplication();
    – Right below that, add
    JUCE_CREATE_APPLICATION_DEFINE (juce::CustomStandaloneFilterApp)
    – A little further down, comment out JUCE_MAIN_FUNCTION_DEFINITION

  • In CustomStandaloneFilterWindow.h:
    – In the StandaloneFilterWindow constructor, add setUsingNativeTitleBar(true); right above setTitleBarButtonsRequired(…).

Build and run. You should now see the native titlebar on the window instead of the JUCE titlebar.

Now, if you want to have the Audio/Midi dialog appear from your own component, do this:

  • In PluginEditor.h
    • Add #include “CustomStandaloneFilterWindow.h”
    • Add a TextButton and in the onClick handler or buttonClicked() callback, add this:
      juce::StandalonePluginHolder::getInstance()->showAudioSettingsDialog();

That’s it. Hope that helps.

8 Likes

Here’s the sample plugin project:

CustomStandalone.zip (22.6 KB)

3 Likes

Brilliant, that is the first time I have got it to work!

Slight correction, these bits:

– Near the bottom of the file, comment out extern juce::JUCEApplicationBase* juce_CreateApplication();
– Right below that, add
JUCE_CREATE_APPLICATION_DEFINE (juce::CustomStandaloneFilterApp)
– A little further down, comment out JUCE_MAIN_FUNCTION_DEFINITION

Are in the CustomStandalone.cpp

Good catch! I just corrected the original post.

Thank you!

Cool! How would you go about removing the native header and frame to have it full screen?

I’m EXTREMELY grateful for you working through this and sharing your knowledge. This really feels like it should be as simple as instantiating your own StandaloneFilterWindow class and #including it and passing it as an argument into some function or something. Unlike most of Juce which feels super intuitive, having to do all of this certainly was not.

For anyone coming to this now, I did have to modify some steps to make it work for me. To follow all of the instructions in @pizzafilms’ guide, I had to copy juce_audio_plugin_client_Standalone.cpp
and then in the Standalone folder:
juce_StandaloneFilterApp.cpp, juce_StandaloneFilterWindow.h

Between the three I could follow the steps and make it work. Thanks @pizzafilms!

1 Like

Another simple solution that does not require copying existing classes is to call setUsingNativeTitleBar in your editor constructor, or in your processor createEditor.
Something like:

auto* topLevel = juce::TopLevelWindow::getTopLevelWindow(0);
if (topLevel) topLevel->setUsingNativeTitleBar(true);

Thanks for that! Is there a way to call the audio settings modal using this method?

Edit: Nm, I see - just import StandalonePluginHolder from juce_StandaloneFilterWindow and call juce::StandalonePluginHolder::getInstance()->showAudioSettingsDialog();. I still think the original method in this post is the way to go because it gives you freedom to do whatever you want but this is super useful for just getting it done.

True, and it looks like this is also the only way if you want to customize the audio settings window (outside of simple lookAndFeel that is, by setting the default look and feel).

One thing I am still missing is how to have the native title bar respond to Windows dark/light theme settings.

For sure, I haven’t checked my plugin/app yet on Windows but I’ll let you know if I figure anything out on that front.

I’m having a hard time figuring out how to set the background color of the dropdowns/input boxes themselves in the audio settings window. Were you able to get that working?

You can set the lookand feel with juce::LookAndFeel::setDefaultLookAndFeel just before calling the show metohd.
I whish there was a simpler way to set a lookandfeel specificaly for that window (maybe there is and I missed it?), as well as some common options like whether you want a native title bar or not, the MIDI settings, the mute toggle with the notification mechanism, maybe the width, etc.