1#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
3using System.Collections.Generic;
4using System.Runtime.InteropServices;
8 public class StandaloneFileBrowserWindows : IStandaloneFileBrowser<ItemWithStream>
10 private const int BufferSize = 2048;
12 [DllImport(
"StandaloneFileBrowser", CharSet = CharSet.Unicode)]
14 [MarshalAs(UnmanagedType.LPWStr)]
string title, [MarshalAs(UnmanagedType.LPWStr)]
string directory,
15 [MarshalAs(UnmanagedType.LPWStr)]
string extension,
bool multiselect);
17 [DllImport(
"StandaloneFileBrowser", CharSet = CharSet.Unicode)]
19 [MarshalAs(UnmanagedType.LPWStr)]
string title, [MarshalAs(UnmanagedType.LPWStr)]
string directory,
20 [MarshalAs(UnmanagedType.LPWStr)]
string extension,
bool multiselect, AsyncCallback callback);
22 [DllImport(
"StandaloneFileBrowser", CharSet = CharSet.Unicode)]
24 [MarshalAs(UnmanagedType.LPWStr)]
string title, [MarshalAs(UnmanagedType.LPWStr)]
string directory,
27 [DllImport(
"StandaloneFileBrowser", CharSet = CharSet.Unicode)]
29 [MarshalAs(UnmanagedType.LPWStr)]
string title, [MarshalAs(UnmanagedType.LPWStr)]
string directory,
30 bool multiselect, AsyncCallback callback);
32 [DllImport(
"StandaloneFileBrowser", CharSet = CharSet.Unicode)]
34 [MarshalAs(UnmanagedType.LPWStr)]
string title, [MarshalAs(UnmanagedType.LPWStr)]
string directory,
35 [MarshalAs(UnmanagedType.LPWStr)]
string defaultName, [MarshalAs(UnmanagedType.LPWStr)]
string extension);
37 [DllImport(
"StandaloneFileBrowser", CharSet = CharSet.Unicode)]
39 [MarshalAs(UnmanagedType.LPWStr)]
string title, [MarshalAs(UnmanagedType.LPWStr)]
string directory,
40 [MarshalAs(UnmanagedType.LPWStr)]
string defaultName, [MarshalAs(UnmanagedType.LPWStr)]
string extension,
41 AsyncCallback callback);
43 public IList<ItemWithStream> OpenFilePanel(
string title,
string directory, ExtensionFilter[] extensions,
46 var results =
new List<ItemWithStream>();
47 var buffer =
new char[BufferSize];
48 var bufferLock = GCHandle.Alloc(buffer, GCHandleType.Pinned);
50 GetFilterFromFileExtensionList(extensions), multiselect)) ParseResults(buffer, results, multiselect);
52 return results.ToArray();
55 public void OpenFilePanelAsync(
string title,
string directory, ExtensionFilter[] extensions,
bool multiselect,
56 Action<IList<ItemWithStream>> cb)
59 cb(OpenFilePanel(title, directory, extensions, multiselect));
62 public IList<ItemWithStream> OpenFolderPanel(
string title,
string directory,
bool multiselect)
64 var results =
new List<ItemWithStream>();
65 var buffer =
new char[BufferSize];
66 var bufferLock = GCHandle.Alloc(buffer, GCHandleType.Pinned);
67 if (
DialogOpenFolderPanel(bufferLock.AddrOfPinnedObject(), BufferSize, title, directory, multiselect))
68 ParseResults(buffer, results, multiselect);
73 public void OpenFolderPanelAsync(
string title,
string directory,
bool multiselect,
74 Action<IList<ItemWithStream>> cb)
77 cb(OpenFolderPanel(title, directory, multiselect));
80 public ItemWithStream SaveFilePanel(
string title,
string directory,
string defaultName,
81 ExtensionFilter[] extensions)
83 var results =
new List<ItemWithStream>();
84 var buffer =
new char[BufferSize];
85 var bufferLock = GCHandle.Alloc(buffer, GCHandleType.Pinned);
86 if (
DialogSaveFilePanel(bufferLock.AddrOfPinnedObject(), BufferSize, title, directory, defaultName,
87 GetFilterFromFileExtensionList(extensions))) ParseResults(buffer, results,
false);
89 return results.Count > 0 ? results[0] :
null;
92 public void SaveFilePanelAsync(
string title,
string directory,
string defaultName, ExtensionFilter[] extensions,
93 Action<ItemWithStream> cb)
96 cb(SaveFilePanel(title, directory, defaultName, extensions));
99 private static string GetFilterFromFileExtensionList(ExtensionFilter[] extensions)
101 var filterString =
"";
102 if (extensions !=
null)
103 foreach (var extension
in extensions)
105 if (!
string.IsNullOrWhiteSpace(extension.Name))
107 filterString += extension.Name;
111 var descriptionString =
"";
112 foreach (var format
in extension.Extensions)
114 if (descriptionString !=
"") descriptionString +=
",";
115 descriptionString +=
"(*" + (format[0] ==
'.' ? format.Substring(1) : format) +
")";
118 filterString += descriptionString;
121 filterString +=
"\0";
122 foreach (var format
in extension.Extensions)
123 filterString +=
"*" + (format[0] ==
'.' ? format.Substring(1) : format) +
";";
124 filterString +=
"\0";
127 filterString +=
"\0";
131 private static void ParseResults(
char[] buffer, List<ItemWithStream> results,
bool multiselect)
133 var currentStringBytes =
new List<char>();
134 foreach (var c
in buffer)
138 var currentString =
new string(currentStringBytes.ToArray());
139 if (!
string.IsNullOrWhiteSpace(currentString) && currentString !=
"\0")
141 var filename = multiselect && results.Count > 0
142 ? $
"{results[0].Name}\\{currentString}"
144 results.Add(
new ItemWithStream
150 currentStringBytes.Clear();
154 currentStringBytes.Add(c);
157 if (multiselect && results.Count > 1) results.RemoveAt(0);
const char * DialogOpenFilePanel(const char *title, const char *directory, const char *filters, bool multiselect)
void DialogOpenFilePanelAsync(const char *title, const char *directory, const char *filters, bool multiselect, callbackFunc cb)
const char * DialogSaveFilePanel(const char *title, const char *directory, const char *defaultName, const char *filters)
void DialogSaveFilePanelAsync(const char *title, const char *directory, const char *defaultName, const char *filters, callbackFunc cb)
const char * DialogOpenFolderPanel(const char *title, const char *directory, bool multiselect)
void DialogOpenFolderPanelAsync(const char *title, const char *directory, bool multiselect, callbackFunc cb)