#if UNITY_STANDALONE_OSX || UNITY_EDITOR_OSX using System; using System.Collections.Generic; using System.IO; using System.Runtime.InteropServices; using System.Threading.Tasks; namespace TriLibCore.SFB { public class StandaloneFileBrowserMac : IStandaloneFileBrowser { private static Action> _openFileCb; private static Action> _openFolderCb; private static Action _saveFileCb; [UnmanagedFunctionPointer(CallingConvention.StdCall)] public delegate void AsyncCallback(string path); [AOT.MonoPInvokeCallback(typeof(AsyncCallback))] private static void openFileCb(string result) { _openFileCb.Invoke(ParseResults(result)); } [AOT.MonoPInvokeCallback(typeof(AsyncCallback))] private static void openFolderCb(string result) { _openFolderCb.Invoke(ParseResults(result)); } [AOT.MonoPInvokeCallback(typeof(AsyncCallback))] private static void saveFileCb(string result) { _saveFileCb.Invoke(ParseResults(result)?[0]); } [DllImport("StandaloneFileBrowser")] private static extern IntPtr DialogOpenFilePanel(string title, string directory, string extension, bool multiselect); [DllImport("StandaloneFileBrowser")] private static extern void DialogOpenFilePanelAsync(string title, string directory, string extension, bool multiselect, AsyncCallback callback); [DllImport("StandaloneFileBrowser")] private static extern IntPtr DialogOpenFolderPanel(string title, string directory, bool multiselect); [DllImport("StandaloneFileBrowser")] private static extern void DialogOpenFolderPanelAsync(string title, string directory, bool multiselect, AsyncCallback callback); [DllImport("StandaloneFileBrowser")] private static extern IntPtr DialogSaveFilePanel(string title, string directory, string defaultName, string extension); [DllImport("StandaloneFileBrowser")] private static extern void DialogSaveFilePanelAsync(string title, string directory, string defaultName, string extension, AsyncCallback callback); public IList OpenFilePanel(string title, string directory, ExtensionFilter[] extensions, bool multiselect) { var paths = Marshal.PtrToStringAnsi(DialogOpenFilePanel( title, directory, GetFilterFromFileExtensionList(extensions), multiselect)); return ParseResults(paths); } public void OpenFilePanelAsync(string title, string directory, ExtensionFilter[] extensions, bool multiselect, Action> cb) { _openFileCb = cb; DialogOpenFilePanelAsync( title, directory, GetFilterFromFileExtensionList(extensions), multiselect, openFileCb); } public IList OpenFolderPanel(string title, string directory, bool multiselect) { var paths = Marshal.PtrToStringAnsi(DialogOpenFolderPanel( title, directory, multiselect)); return ParseResults(paths); } public void OpenFolderPanelAsync(string title, string directory, bool multiselect, Action> cb) { _openFolderCb = cb; DialogOpenFolderPanelAsync( title, directory, multiselect, openFolderCb); } public ItemWithStream SaveFilePanel(string title, string directory, string defaultName, ExtensionFilter[] extensions) { var filename = Marshal.PtrToStringAnsi(DialogSaveFilePanel( title, directory, defaultName, GetFilterFromFileExtensionList(extensions))); return new ItemWithStream { Name = filename }; } public void SaveFilePanelAsync(string title, string directory, string defaultName, ExtensionFilter[] extensions, Action cb) { _saveFileCb = cb; DialogSaveFilePanelAsync( title, directory, defaultName, GetFilterFromFileExtensionList(extensions), saveFileCb); } private static string GetFilterFromFileExtensionList(ExtensionFilter[] extensions) { if (extensions == null) { return ""; } var filterString = ""; foreach (var filter in extensions) { var hasFormat = false; filterString += filter.Name + ";"; foreach (var format in filter.Extensions) { if (hasFormat) { filterString += ","; } filterString += (format[0] == '.' ? format.Substring(1) : format); hasFormat = true; } filterString += "|"; } filterString = filterString.Remove(filterString.Length - 1); return filterString; } private static IList ParseResults(string paths) { if (paths != null) { var filenames = paths.Split((char)28); var result = new ItemWithStream[filenames.Length]; for (var i = 0; i < filenames.Length; i++) { result[i] = new ItemWithStream() { Name = filenames[i]//, //Stream = File.OpenRead(filenames[i]) }; } return result; } return null; } } } #endif