diff --git a/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h b/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h index 04a8f2f43e..c81d8479f0 100644 --- a/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h +++ b/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h @@ -723,26 +723,11 @@ public: //============================================================================== typedef StandalonePluginHolder::PluginInOuts PluginInOuts; - //============================================================================== - /** Creates a window with a given title and colour. - The settings object can be a PropertySet that the class should use to - store its settings (it can also be null). If takeOwnershipOfSettings is - true, then the settings object will be owned and deleted by this object. - */ StandaloneFilterWindow (const String& title, Colour backgroundColour, - PropertySet* settingsToUse, - bool takeOwnershipOfSettings, - const String& preferredDefaultDeviceName = String(), - const AudioDeviceManager::AudioDeviceSetup* preferredSetupOptions = nullptr, - const Array& constrainToConfiguration = {}, - #if JUCE_ANDROID || JUCE_IOS - bool autoOpenMidiDevices = true - #else - bool autoOpenMidiDevices = false - #endif - ) + std::unique_ptr pluginHolderIn) : DocumentWindow (title, backgroundColour, DocumentWindow::minimiseButton | DocumentWindow::closeButton), + pluginHolder (std::move (pluginHolderIn)), optionsButton ("Options") { setConstrainer (&decoratorConstrainer); @@ -757,10 +742,6 @@ public: optionsButton.setTriggeredOnMouseDown (true); #endif - pluginHolder.reset (new StandalonePluginHolder (settingsToUse, takeOwnershipOfSettings, - preferredDefaultDeviceName, preferredSetupOptions, - constrainToConfiguration, autoOpenMidiDevices)); - #if JUCE_IOS || JUCE_ANDROID setFullScreen (true); updateContent(); @@ -809,6 +790,36 @@ public: #endif } + //============================================================================== + /** Creates a window with a given title and colour. + The settings object can be a PropertySet that the class should use to + store its settings (it can also be null). If takeOwnershipOfSettings is + true, then the settings object will be owned and deleted by this object. + */ + StandaloneFilterWindow (const String& title, + Colour backgroundColour, + PropertySet* settingsToUse, + bool takeOwnershipOfSettings, + const String& preferredDefaultDeviceName = String(), + const AudioDeviceManager::AudioDeviceSetup* preferredSetupOptions = nullptr, + const Array& constrainToConfiguration = {}, + #if JUCE_ANDROID || JUCE_IOS + bool autoOpenMidiDevices = true + #else + bool autoOpenMidiDevices = false + #endif + ) + : StandaloneFilterWindow (title, + backgroundColour, + std::make_unique (settingsToUse, + takeOwnershipOfSettings, + preferredDefaultDeviceName, + preferredSetupOptions, + constrainToConfiguration, + autoOpenMidiDevices)) + { + } + ~StandaloneFilterWindow() override { #if (! JUCE_IOS) && (! JUCE_ANDROID) diff --git a/modules/juce_audio_plugin_client/juce_audio_plugin_client_Standalone.cpp b/modules/juce_audio_plugin_client/juce_audio_plugin_client_Standalone.cpp index ed82f375a7..820fd22943 100644 --- a/modules/juce_audio_plugin_client/juce_audio_plugin_client_Standalone.cpp +++ b/modules/juce_audio_plugin_client/juce_audio_plugin_client_Standalone.cpp @@ -70,7 +70,7 @@ public: { PropertiesFile::Options options; - options.applicationName = appName; + options.applicationName = CharPointer_UTF8 (JucePlugin_Name); options.filenameSuffix = ".settings"; options.osxLibrarySubFolder = "Application Support"; #if JUCE_LINUX || JUCE_BSD @@ -82,46 +82,72 @@ public: appProperties.setStorageParameters (options); } - const String getApplicationName() override { return appName; } + const String getApplicationName() override { return CharPointer_UTF8 (JucePlugin_Name); } const String getApplicationVersion() override { return JucePlugin_VersionString; } bool moreThanOneInstanceAllowed() override { return true; } void anotherInstanceStarted (const String&) override {} virtual StandaloneFilterWindow* createWindow() { - #ifdef JucePlugin_PreferredChannelConfigurations - StandalonePluginHolder::PluginInOuts channels[] = { JucePlugin_PreferredChannelConfigurations }; - #endif + if (Desktop::getInstance().getDisplays().displays.isEmpty()) + { + // No displays are available, so no window will be created! + jassertfalse; + return nullptr; + } return new StandaloneFilterWindow (getApplicationName(), LookAndFeel::getDefaultLookAndFeel().findColour (ResizableWindow::backgroundColourId), - appProperties.getUserSettings(), - false, {}, nullptr - #ifdef JucePlugin_PreferredChannelConfigurations - , juce::Array (channels, juce::numElementsInArray (channels)) - #else - , {} - #endif - #if JUCE_DONT_AUTO_OPEN_MIDI_DEVICES_ON_MOBILE - , false - #endif - ); + createPluginHolder()); + } + + virtual std::unique_ptr createPluginHolder() + { + constexpr auto autoOpenMidiDevices = + #if (JUCE_ANDROID || JUCE_IOS) && ! JUCE_DONT_AUTO_OPEN_MIDI_DEVICES_ON_MOBILE + true; + #else + false; + #endif + + + #ifdef JucePlugin_PreferredChannelConfigurations + constexpr StandalonePluginHolder::PluginInOuts channels[] { JucePlugin_PreferredChannelConfigurations }; + const Array channelConfig {channels, juce::numElementsInArray (channels)); + #else + const Array channelConfig; + #endif + + return std::make_unique (appProperties.getUserSettings(), + false, + String{}, + nullptr, + channelConfig, + autoOpenMidiDevices); } //============================================================================== void initialise (const String&) override { - mainWindow.reset (createWindow()); + mainWindow = rawToUniquePtr (createWindow()); - #if JUCE_STANDALONE_FILTER_WINDOW_USE_KIOSK_MODE - Desktop::getInstance().setKioskModeComponent (mainWindow.get(), false); - #endif + if (mainWindow != nullptr) + { + #if JUCE_STANDALONE_FILTER_WINDOW_USE_KIOSK_MODE + Desktop::getInstance().setKioskModeComponent (mainWindow.get(), false); + #endif - mainWindow->setVisible (true); + mainWindow->setVisible (true); + } + else + { + pluginHolder = createPluginHolder(); + } } void shutdown() override { + pluginHolder = nullptr; mainWindow = nullptr; appProperties.saveIfNeeded(); } @@ -129,6 +155,9 @@ public: //============================================================================== void systemRequestedQuit() override { + if (pluginHolder != nullptr) + pluginHolder->savePluginState(); + if (mainWindow != nullptr) mainWindow->pluginHolder->savePluginState(); @@ -151,7 +180,7 @@ protected: std::unique_ptr mainWindow; private: - const String appName { CharPointer_UTF8 (JucePlugin_Name) }; + std::unique_ptr pluginHolder; }; } // namespace juce