diff --git a/modules/juce_gui_basics/filebrowser/juce_FileChooser.cpp b/modules/juce_gui_basics/filebrowser/juce_FileChooser.cpp index 786bb6ab11..d5321163d5 100644 --- a/modules/juce_gui_basics/filebrowser/juce_FileChooser.cpp +++ b/modules/juce_gui_basics/filebrowser/juce_FileChooser.cpp @@ -39,7 +39,8 @@ public: filter (selectsFiles ? owner.filters : String(), selectsDirectories ? "*" : String(), {}), browserComponent (flags, owner.startingFile, &filter, preview), - dialogBox (owner.title, {}, browserComponent, warnAboutOverwrite, browserComponent.findColour (AlertWindow::backgroundColourId)) + dialogBox (owner.title, {}, browserComponent, warnAboutOverwrite, + browserComponent.findColour (AlertWindow::backgroundColourId), owner.parent) {} ~NonNative() @@ -92,10 +93,12 @@ FileChooser::FileChooser (const String& chooserBoxTitle, const File& currentFileOrDirectory, const String& fileFilters, const bool useNativeBox, - const bool treatFilePackagesAsDirectories) + const bool treatFilePackagesAsDirectories, + Component* parentComponentToUse) : title (chooserBoxTitle), filters (fileFilters), startingFile (currentFileOrDirectory), + parent (parentComponentToUse), useNativeDialogBox (useNativeBox && isPlatformDialogAvailable()), treatFilePackagesAsDirs (treatFilePackagesAsDirectories) { diff --git a/modules/juce_gui_basics/filebrowser/juce_FileChooser.h b/modules/juce_gui_basics/filebrowser/juce_FileChooser.h index 59497f2714..f80f7e70c9 100644 --- a/modules/juce_gui_basics/filebrowser/juce_FileChooser.h +++ b/modules/juce_gui_basics/filebrowser/juce_FileChooser.h @@ -107,6 +107,11 @@ public: selection of files inside packages when invoked on OS X and when using native dialog boxes. + @param parentComponent An optional component which should be the parent + for the file chooser. If this is a nullptr then the + FileChooser will be a top-level window. AUv3s on iOS + must specify this parameter as opening a top-level window + in an AUv3 is forbidden due to sandbox restrictions. @see browseForFileToOpen, browseForFileToSave, browseForDirectory */ @@ -114,7 +119,8 @@ public: const File& initialFileOrDirectory = File(), const String& filePatternsAllowed = String(), bool useOSNativeDialogBox = true, - bool treatFilePackagesAsDirectories = false); + bool treatFilePackagesAsDirectories = false, + Component* parentComponent = nullptr); /** Destructor. */ ~FileChooser(); @@ -300,6 +306,7 @@ private: //============================================================================== String title, filters; File startingFile; + Component* parent; Array results; const bool useNativeDialogBox; const bool treatFilePackagesAsDirs; diff --git a/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.cpp b/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.cpp index 3847c46dae..4fbbafceea 100644 --- a/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.cpp +++ b/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.cpp @@ -94,8 +94,9 @@ FileChooserDialogBox::FileChooserDialogBox (const String& name, const String& instructions, FileBrowserComponent& chooserComponent, bool shouldWarn, - Colour backgroundColour) - : ResizableWindow (name, backgroundColour, true), + Colour backgroundColour, + Component* parentComponent) + : ResizableWindow (name, backgroundColour, parentComponent == nullptr), warnAboutOverwritingExistingFiles (shouldWarn) { content = new ContentComponent (name, instructions, chooserComponent); @@ -111,6 +112,9 @@ FileChooserDialogBox::FileChooserDialogBox (const String& name, content->chooserComponent.addListener (this); FileChooserDialogBox::selectionChanged(); + + if (parentComponent != nullptr) + parentComponent->addAndMakeVisible (this); } FileChooserDialogBox::~FileChooserDialogBox() diff --git a/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.h b/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.h index 16c006b8b9..68159c3d02 100644 --- a/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.h +++ b/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.h @@ -81,6 +81,11 @@ public: if they try to select a file that already exists. (This flag is only used when saving files) @param backgroundColour the background colour for the top level window + @param parentComponent an optional component which should be the parent + for the file chooser. If this is a nullptr then the + dialog box will be a top-level window. AUv3s on iOS + must specify this parameter as opening a top-level window + in an AUv3 is forbidden due to sandbox restrictions. @see FileBrowserComponent, FilePreviewComponent */ @@ -88,7 +93,8 @@ public: const String& instructions, FileBrowserComponent& browserComponent, bool warnAboutOverwritingExistingFiles, - Colour backgroundColour); + Colour backgroundColour, + Component* parentComponent = nullptr); /** Destructor. */ ~FileChooserDialogBox(); diff --git a/modules/juce_gui_basics/native/juce_ios_FileChooser.mm b/modules/juce_gui_basics/native/juce_ios_FileChooser.mm index 67fd14a48a..438d16a8e7 100644 --- a/modules/juce_gui_basics/native/juce_ios_FileChooser.mm +++ b/modules/juce_gui_basics/native/juce_ios_FileChooser.mm @@ -87,15 +87,22 @@ public: if (SystemStats::isRunningInAppExtensionSandbox()) { - [controller.get() setModalPresentationStyle:UIModalPresentationFullScreen]; - - if (auto* editorPeer = ComponentPeer::getPeer (0)) + if (fileChooser.parent != nullptr) { - auto chooserBounds = editorPeer->getComponent().getLocalBounds(); + [controller.get() setModalPresentationStyle:UIModalPresentationFullScreen]; + + auto chooserBounds = fileChooser.parent->getBounds(); setBounds (chooserBounds); setAlwaysOnTop (true); - editorPeer->getComponent().addAndMakeVisible (this); + fileChooser.parent->addAndMakeVisible (this); + } + else + { + // Opening a native top-level window in an AUv3 is not allowed (sandboxing). You need to specify a + // parent component (for example your editor) to parent the native file chooser window. To do this + // specify a parent component in the FileChooser's constructor! + jassert (fileChooser.parent != nullptr); } } else