diff --git a/Source/Engine/Platform/Base/FileSystemBase.cpp b/Source/Engine/Platform/Base/FileSystemBase.cpp
index 1df3970c3..658100446 100644
--- a/Source/Engine/Platform/Base/FileSystemBase.cpp
+++ b/Source/Engine/Platform/Base/FileSystemBase.cpp
@@ -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;
diff --git a/Source/Engine/Platform/Base/FileSystemBase.h b/Source/Engine/Platform/Base/FileSystemBase.h
index d2e0af872..c99fd74da 100644
--- a/Source/Engine/Platform/Base/FileSystemBase.h
+++ b/Source/Engine/Platform/Base/FileSystemBase.h
@@ -76,7 +76,7 @@ DECLARE_SCRIPTING_TYPE_MINIMAL(FileSystemBase);
/// The dialog title.
/// The output path.
/// True if failed, otherwise false.
- 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);
///
/// Opens a standard file explorer application and navigates to the given directory.
diff --git a/Source/Engine/Platform/Mac/MacFileSystem.cpp b/Source/Engine/Platform/Mac/MacFileSystem.cpp
index 7aeb1fcef..b0529e2d1 100644
--- a/Source/Engine/Platform/Mac/MacFileSystem.cpp
+++ b/Source/Engine/Platform/Mac/MacFileSystem.cpp
@@ -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
#include
#include
+#include
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 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& 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& 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());
diff --git a/Source/Engine/Platform/Mac/MacFileSystem.h b/Source/Engine/Platform/Mac/MacFileSystem.h
index 534a387bd..d1ebc6867 100644
--- a/Source/Engine/Platform/Mac/MacFileSystem.h
+++ b/Source/Engine/Platform/Mac/MacFileSystem.h
@@ -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& filenames);
+ static bool ShowSaveFileDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& filter, bool multiSelect, const StringView& title, Array& 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);
diff --git a/Source/Engine/Platform/Mac/MacPlatform.cpp b/Source/Engine/Platform/Mac/MacPlatform.cpp
index ae1e55e5d..0490520d3 100644
--- a/Source/Engine/Platform/Mac/MacPlatform.cpp
+++ b/Source/Engine/Platform/Mac/MacPlatform.cpp
@@ -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)
diff --git a/Source/Engine/Platform/Mac/MacUtils.h b/Source/Engine/Platform/Mac/MacUtils.h
index 50caba425..59acb655b 100644
--- a/Source/Engine/Platform/Mac/MacUtils.h
+++ b/Source/Engine/Platform/Mac/MacUtils.h
@@ -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();
};
diff --git a/Source/Engine/Platform/Windows/WindowsFileSystem.cpp b/Source/Engine/Platform/Windows/WindowsFileSystem.cpp
index 176197bc6..746566f50 100644
--- a/Source/Engine/Platform/Windows/WindowsFileSystem.cpp
+++ b/Source/Engine/Platform/Windows/WindowsFileSystem.cpp
@@ -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;
diff --git a/Source/Engine/Platform/Windows/WindowsFileSystem.h b/Source/Engine/Platform/Windows/WindowsFileSystem.h
index a1569fb6e..1e4927442 100644
--- a/Source/Engine/Platform/Windows/WindowsFileSystem.h
+++ b/Source/Engine/Platform/Windows/WindowsFileSystem.h
@@ -38,7 +38,7 @@ public:
// [Win32FileSystem]
static bool ShowOpenFileDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& filter, bool multiSelect, const StringView& title, Array& filenames);
static bool ShowSaveFileDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& filter, bool multiSelect, const StringView& title, Array& 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);
};