I gave it a go and this is patch for juce_mac_FileChooser.mm is what I came up with so far. It seems to work for me, but I’m not sure everything cleans up correctly with the addToDesktop call.
I also wondered whether there is not a simpler way to deal with the Cocoa Class naming fiasko (ObjCClass…). I vaguely remember doing something with the Preprocessor that would enable unique obj-c classnames for each project without having to do everything with C.
A bit of an issue with the whole thing is that windows uses a layout with the preview component on the right side while OSX wants to but it below the file selector panel. So using the same component seems a bit tricky as one need to be tall and the other wide. Nevertheless I prefer this to using the JUCE custom panel.
diff --git a/modules/juce_gui_basics/native/juce_mac_FileChooser.mm b/modules/juce_gui_basics/native/juce_mac_FileChooser.mm
index f256067..20fbba8 100644
--- a/modules/juce_gui_basics/native/juce_mac_FileChooser.mm
+++ b/modules/juce_gui_basics/native/juce_mac_FileChooser.mm
@@ -29,9 +29,11 @@ struct FileChooserDelegateClass : public ObjCClass <NSObject>
FileChooserDelegateClass() : ObjCClass <NSObject> ("JUCEFileChooser_")
{
addIvar<StringArray*> ("filters");
+ addIvar<FilePreviewComponent*> ("filePreviewComponent");
addMethod (@selector (dealloc), dealloc, "v@:");
addMethod (@selector (panel:shouldShowFilename:), shouldShowFilename, "c@:@@");
+ addMethod (@selector (panelSelectionDidChange:), selectionDidChange, "c@");
#if defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
addProtocol (@protocol (NSOpenSavePanelDelegate));
@@ -45,6 +47,11 @@ struct FileChooserDelegateClass : public ObjCClass <NSObject>
object_setInstanceVariable (self, "filters", filters);
}
+ static void setFilePreviewComponent (id self, FilePreviewComponent* previewComponent)
+ {
+ object_setInstanceVariable (self, "filePreviewComponent", previewComponent);
+ }
+
private:
static void dealloc (id self, SEL)
{
@@ -81,6 +88,33 @@ private:
return f.isDirectory()
&& ! [[NSWorkspace sharedWorkspace] isFilePackageAtPath: filename];
}
+
+ static void selectionDidChange (id self, SEL, id sender) {
+ FilePreviewComponent* const previewComp = getIvar<FilePreviewComponent*> (self, "filePreviewComponent");
+ String filePath;
+ if ([sender isKindOfClass:[NSOpenPanel class]])
+ {
+ NSOpenPanel* panel = (NSOpenPanel*)sender;
+ NSArray* urls = [panel URLs];
+ for (unsigned int i = 0; i < [urls count]; ++i)
+ {
+ if (filePath.isEmpty())
+ {
+ filePath = nsStringToJuce([[urls objectAtIndex: i] path]);
+ }
+ else
+ {
+ filePath += " " + nsStringToJuce([[urls objectAtIndex: i] path]);
+ }
+ }
+ }
+ else if ([sender isKindOfClass:[NSSavePanel class]])
+ {
+ NSSavePanel* panel = (NSSavePanel*)sender;
+ filePath = nsStringToJuce([[panel URL] path]);
+ }
+ previewComp->selectedFileChanged(File(filePath));
+ }
};
static NSMutableArray* createAllowedTypesArray (const StringArray& filters)
@@ -113,7 +147,7 @@ void FileChooser::showPlatformDialog (Array<File>& results,
bool isSaveDialogue,
bool /*warnAboutOverwritingExistingFiles*/,
bool selectMultipleFiles,
- FilePreviewComponent* /*extraInfoComponent*/)
+ FilePreviewComponent* extraInfoComponent)
{
JUCE_AUTORELEASEPOOL
{
@@ -150,6 +184,16 @@ void FileChooser::showPlatformDialog (Array<File>& results,
[openPanel setAllowsMultipleSelection: selectMultipleFiles];
[openPanel setResolvesAliases: YES];
}
+
+ if (extraInfoComponent != nullptr)
+ {
+ NSView* view = [[[NSView alloc] initWithFrame:NSMakeRect(0, 0, extraInfoComponent->getWidth(), extraInfoComponent->getHeight())] autorelease];
+ extraInfoComponent->addToDesktop(0, (void*)view);
+ extraInfoComponent->setVisible(view);
+ FileChooserDelegateClass::setFilePreviewComponent(delegate, extraInfoComponent);
+
+ [panel setAccessoryView:view];
+ }
[panel setDelegate: delegate];