Add open/save file dialogs for Mac

This commit is contained in:
Wojtek Figat
2022-01-18 13:45:48 +01:00
parent 35d9016053
commit 54db90e040
8 changed files with 125 additions and 7 deletions

View File

@@ -20,7 +20,7 @@ bool FileSystemBase::ShowSaveFileDialog(Window* parentWindow, const StringView&
return true;
}
bool FileSystemBase::ShowBrowseFolderDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& title, StringView& path)
bool FileSystemBase::ShowBrowseFolderDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& title, String& path)
{
// No supported
return true;

View File

@@ -76,7 +76,7 @@ DECLARE_SCRIPTING_TYPE_MINIMAL(FileSystemBase);
/// <param name="title">The dialog title.</param>
/// <param name="path">The output path.</param>
/// <returns>True if failed, otherwise false.</returns>
API_FUNCTION() static bool ShowBrowseFolderDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& title, API_PARAM(Out) StringView& path);
API_FUNCTION() static bool ShowBrowseFolderDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& title, API_PARAM(Out) String& path);
/// <summary>
/// Opens a standard file explorer application and navigates to the given directory.

View File

@@ -3,6 +3,7 @@
#if PLATFORM_MAC
#include "MacFileSystem.h"
#include "MacUtils.h"
#include "Engine/Platform/File.h"
#include "Engine/Core/Types/String.h"
#include "Engine/Core/Types/StringView.h"
@@ -19,9 +20,122 @@
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <AppKit/AppKit.h>
const DateTime UnixEpoch(1970, 1, 1);
void InitMacDialog(NSSavePanel* dialog, const StringView& initialDirectory, const StringView& filter, const StringView& title)
{
if (initialDirectory.HasChars())
{
[dialog setDirectoryURL:[NSURL fileURLWithPath:(NSString*)MacUtils::ToString(initialDirectory) isDirectory:YES]];
}
if (filter.HasChars())
{
// TODO: finish file tpye filter support
/*NSMutableArray* fileTypes = [[NSMutableArray alloc] init];
Array<String> entries;
String(filter).Split('\0', entries);
for (int32 i = 1; i < entries.Count(); i += 2)
{
String extension = entries[i];
if (extension.StartsWith(TEXT("*.")))
extension = extension.Substring(2);
[fileTypes addObject:(NSString*)MacUtils::ToString(extension)];
}
[dialog setAllowedFileTypes:fileTypes];*/
}
if (title.HasChars())
{
[dialog setMessage:(NSString*)MacUtils::ToString(title)];
}
}
bool MacFileSystem::ShowOpenFileDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& filter, bool multiSelect, const StringView& title, Array<String>& filenames)
{
bool result = true;
@autoreleasepool {
NSWindow* focusedWindow = [[NSApplication sharedApplication] keyWindow];
NSOpenPanel* dialog = [NSOpenPanel openPanel];
[dialog setCanChooseFiles:YES];
[dialog setCanChooseDirectories:NO];
[dialog setAllowsMultipleSelection:multiSelect ? YES : NO];
InitMacDialog(dialog, initialDirectory, filter, title);
if ([dialog runModal] == NSModalResponseOK)
{
if (multiSelect)
{
const NSArray* urls = [dialog URLs];
for (int32 i = 0; i < [urls count]; i++)
filenames.Add(MacUtils::ToString((CFStringRef)[[urls objectAtIndex:i] path]));
}
else
{
const NSURL* url = [dialog URL];
filenames.Add(MacUtils::ToString((CFStringRef)[url path]));
}
result = false;
}
[focusedWindow makeKeyAndOrderFront:nil];
}
return result;
}
bool MacFileSystem::ShowSaveFileDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& filter, bool multiSelect, const StringView& title, Array<String>& filenames)
{
bool result = true;
@autoreleasepool {
NSWindow* focusedWindow = [[NSApplication sharedApplication] keyWindow];
NSSavePanel* dialog = [NSSavePanel savePanel];
[dialog setExtensionHidden:NO];
InitMacDialog(dialog, initialDirectory, filter, title);
if ([dialog runModal] == NSModalResponseOK)
{
const NSURL* url = [dialog URL];
filenames.Add(MacUtils::ToString((CFStringRef)[url path]));
result = false;
}
[focusedWindow makeKeyAndOrderFront:nil];
}
return result;
}
bool MacFileSystem::ShowBrowseFolderDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& title, String& path)
{
bool result = true;
@autoreleasepool {
NSWindow* focusedWindow = [[NSApplication sharedApplication] keyWindow];
NSOpenPanel* dialog = [NSOpenPanel openPanel];
[dialog setCanChooseFiles:NO];
[dialog setCanChooseDirectories:YES];
[dialog setCanCreateDirectories:YES];
[dialog setAllowsMultipleSelection:NO];
InitMacDialog(dialog, initialDirectory, StringView::Empty, title);
if ([dialog runModal] == NSModalResponseOK)
{
const NSURL* url = [dialog URL];
path = MacUtils::ToString((CFStringRef)[url path]);
result = false;
}
[focusedWindow makeKeyAndOrderFront:nil];
}
return result;
}
bool MacFileSystem::ShowFileExplorer(const StringView& path)
{
return Platform::StartProcess(TEXT("open"), String::Format(TEXT("\"{0}\""), path), StringView::Empty) != 0;
}
bool MacFileSystem::CreateDirectory(const StringView& path)
{
const StringAsANSI<> pathAnsi(*path, path.Length());

View File

@@ -14,6 +14,10 @@ class FLAXENGINE_API MacFileSystem : public FileSystemBase
public:
// [FileSystemBase]
static bool ShowOpenFileDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& filter, bool multiSelect, const StringView& title, Array<String, HeapAllocation>& filenames);
static bool ShowSaveFileDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& filter, bool multiSelect, const StringView& title, Array<String, HeapAllocation>& filenames);
static bool ShowBrowseFolderDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& title, String& path);
static bool ShowFileExplorer(const StringView& path);
static bool CreateDirectory(const StringView& path);
static bool DeleteDirectory(const String& path, bool deleteContents = true);
static bool DirectoryExists(const StringView& path);

View File

@@ -67,9 +67,9 @@ String MacUtils::ToString(CFStringRef str)
return result;
}
CFStringRef MacUtils::ToString(const String& str)
CFStringRef MacUtils::ToString(const StringView& str)
{
return CFStringCreateWithBytes(nullptr, (const UInt8*)str.Get(), str.Length() * sizeof(Char), kCFStringEncodingUTF16LE, false);
return CFStringCreateWithBytes(nullptr, (const UInt8*)str.GetNonTerminatedText(), str.Length() * sizeof(Char), kCFStringEncodingUTF16LE, false);
}
Vector2 MacUtils::PosToCoca(const Vector2& pos)

View File

@@ -9,7 +9,7 @@ class FLAXENGINE_API MacUtils
{
public:
static String ToString(CFStringRef str);
static CFStringRef ToString(const String& str);
static CFStringRef ToString(const StringView& str);
static Vector2 PosToCoca(const Vector2& pos);
static Vector2 GetScreensOrigin();
};

View File

@@ -290,7 +290,7 @@ bool WindowsFileSystem::ShowSaveFileDialog(Window* parentWindow, const StringVie
return result;
}
bool WindowsFileSystem::ShowBrowseFolderDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& title, StringView& path)
bool WindowsFileSystem::ShowBrowseFolderDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& title, String& path)
{
bool result = true;

View File

@@ -38,7 +38,7 @@ public:
// [Win32FileSystem]
static bool ShowOpenFileDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& filter, bool multiSelect, const StringView& title, Array<String, HeapAllocation>& filenames);
static bool ShowSaveFileDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& filter, bool multiSelect, const StringView& title, Array<String, HeapAllocation>& filenames);
static bool ShowBrowseFolderDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& title, StringView& path);
static bool ShowBrowseFolderDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& title, String& path);
static bool ShowFileExplorer(const StringView& path);
};