Add package content.

This commit is contained in:
2024-10-04 17:39:09 +02:00
parent 37292d7746
commit 177261bce2
26 changed files with 675 additions and 0 deletions

7
LICENSE.md.meta Normal file
View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: bd207668b9a801d4881b011eac892fca
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
Runtime.meta Normal file
View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: cbb403dce8ed7584ba58fb549de45bd3
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

3
Runtime/Native.meta Normal file
View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: aebf597fff444ea7aa6e9421db4883bf
timeCreated: 1728054954

View File

@@ -0,0 +1,97 @@
using System;
using System.Runtime.InteropServices;
namespace NativeFileDialogSharp.Native
{
public struct nfdpathset_t
{
public IntPtr buf;
public IntPtr indices;
public UIntPtr count;
}
public enum nfdresult_t
{
NFD_ERROR,
NFD_OKAY,
NFD_CANCEL
}
public static class NativeFunctions
{
public const string LibraryName = "nfd";
[DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern unsafe nfdresult_t NFD_OpenDialog(byte* filterList, byte* defaultPath, out IntPtr outPath);
[DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern unsafe nfdresult_t NFD_OpenDialogMultiple(byte* filterList, byte* defaultPath,
nfdpathset_t* outPaths);
[DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern unsafe nfdresult_t NFD_SaveDialog(byte* filterList, byte* defaultPath, out IntPtr outPath);
[DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern unsafe nfdresult_t NFD_PickFolder(byte* defaultPath, out IntPtr outPath);
[DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern unsafe byte* NFD_GetError();
[DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern unsafe UIntPtr NFD_PathSet_GetCount(nfdpathset_t* pathSet);
[DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern unsafe byte* NFD_PathSet_GetPath(nfdpathset_t* pathSet, UIntPtr index);
[DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern unsafe void NFD_PathSet_Free(nfdpathset_t* pathSet);
[DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern unsafe void NFD_Dummy();
[DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern unsafe IntPtr NFD_Malloc(UIntPtr bytes);
[DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern unsafe void NFD_Free(IntPtr ptr);
}
public static class NativeFunctions32
{
public const string LibraryName = "nfd_x86";
[DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern unsafe nfdresult_t NFD_OpenDialog(byte* filterList, byte* defaultPath, out IntPtr outPath);
[DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern unsafe nfdresult_t NFD_OpenDialogMultiple(byte* filterList, byte* defaultPath,
nfdpathset_t* outPaths);
[DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern unsafe nfdresult_t NFD_SaveDialog(byte* filterList, byte* defaultPath, out IntPtr outPath);
[DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern unsafe nfdresult_t NFD_PickFolder(byte* defaultPath, out IntPtr outPath);
[DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern unsafe byte* NFD_GetError();
[DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern unsafe UIntPtr NFD_PathSet_GetCount(nfdpathset_t* pathSet);
[DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern unsafe byte* NFD_PathSet_GetPath(nfdpathset_t* pathSet, UIntPtr index);
[DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern unsafe void NFD_PathSet_Free(nfdpathset_t* pathSet);
[DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern unsafe void NFD_Dummy();
[DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern unsafe IntPtr NFD_Malloc(UIntPtr bytes);
[DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern unsafe void NFD_Free(IntPtr ptr);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f2e2abf13b9012b4296a07bf97c360c4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,20 @@
{
"name": "NativeFileDialogSharp",
"rootNamespace": "NativeFileDialogSharp",
"references": [],
"includePlatforms": [
"Editor",
"LinuxStandalone64",
"macOSStandalone",
"WindowsStandalone32",
"WindowsStandalone64"
],
"excludePlatforms": [],
"allowUnsafeCode": true,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: fc0fbc61b4159414f98860d5c96eb9f0
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

206
Runtime/NativeWrappers.cs Normal file
View File

@@ -0,0 +1,206 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using NativeFileDialogSharp.Native;
namespace NativeFileDialogSharp
{
public static class Dialog
{
private static readonly Encoder utf8encoder = Encoding.UTF8.GetEncoder();
private static readonly bool need32bit = Is32BitWindowsOnNetFramework();
private static bool Is32BitWindowsOnNetFramework()
{
try
{
// we call a function that does nothing just to test if we can load it properly
NativeFileDialogSharp.Native.NativeFunctions.NFD_Dummy();
return false;
}
catch
{
// a call to a default library failed, let's attempt the other one
try
{
NativeFileDialogSharp.Native.NativeFunctions32.NFD_Dummy();
return true;
}
catch
{
// both of them failed so we may as well default to the default one for predictability
return false;
}
}
}
private static unsafe byte[] ToUtf8(string s)
{
var byteCount = Encoding.UTF8.GetByteCount(s);
var bytes = new byte[byteCount + 1];
fixed (byte* o = bytes)
fixed (char* input = s)
{
utf8encoder.Convert(input, s.Length, o, bytes.Length, true, out _, out var _,
out var completed);
Debug.Assert(completed);
}
return bytes;
}
private static unsafe int GetNullTerminatedStringLength(byte* nullTerminatedString)
{
int count = 0;
var ptr = nullTerminatedString;
while (*ptr != 0)
{
ptr++;
count++;
}
return count;
}
private static unsafe string FromUtf8(byte* nullTerminatedString)
{
return Encoding.UTF8.GetString(nullTerminatedString, GetNullTerminatedStringLength(nullTerminatedString));
}
public static unsafe DialogResult FileOpen(string filterList = null, string defaultPath = null)
{
fixed (byte* filterListNts = filterList != null ? ToUtf8(filterList) : null)
fixed (byte* defaultPathNts = defaultPath != null ? ToUtf8(defaultPath) : null)
{
string path = null;
string errorMessage = null;
IntPtr outPathIntPtr;
var result = need32bit
? NativeFunctions32.NFD_OpenDialog(filterListNts, defaultPathNts, out outPathIntPtr)
: NativeFunctions.NFD_OpenDialog(filterListNts, defaultPathNts, out outPathIntPtr);
if (result == nfdresult_t.NFD_ERROR)
{
errorMessage = FromUtf8(NativeFunctions.NFD_GetError());
}
else if (result == nfdresult_t.NFD_OKAY)
{
var outPathNts = (byte*)outPathIntPtr.ToPointer();
path = FromUtf8(outPathNts);
NativeFunctions.NFD_Free(outPathIntPtr);
}
return new DialogResult(result, path, null, errorMessage);
}
}
public static unsafe DialogResult FileSave(string filterList = null, string defaultPath = null)
{
fixed (byte* filterListNts = filterList != null ? ToUtf8(filterList) : null)
fixed (byte* defaultPathNts = defaultPath != null ? ToUtf8(defaultPath) : null)
{
string path = null;
string errorMessage = null;
IntPtr outPathIntPtr;
var result = need32bit
? NativeFunctions32.NFD_SaveDialog(filterListNts, defaultPathNts, out outPathIntPtr)
: NativeFunctions.NFD_SaveDialog(filterListNts, defaultPathNts, out outPathIntPtr);
if (result == nfdresult_t.NFD_ERROR)
{
errorMessage = FromUtf8(NativeFunctions.NFD_GetError());
}
else if (result == nfdresult_t.NFD_OKAY)
{
var outPathNts = (byte*)outPathIntPtr.ToPointer();
path = FromUtf8(outPathNts);
NativeFunctions.NFD_Free(outPathIntPtr);
}
return new DialogResult(result, path, null, errorMessage);
}
}
public static unsafe DialogResult FolderPicker(string defaultPath = null)
{
fixed (byte* defaultPathNts = defaultPath != null ? ToUtf8(defaultPath) : null)
{
string path = null;
string errorMessage = null;
IntPtr outPathIntPtr;
var result = need32bit
? NativeFunctions32.NFD_PickFolder(defaultPathNts, out outPathIntPtr)
: NativeFunctions.NFD_PickFolder(defaultPathNts, out outPathIntPtr);
if (result == nfdresult_t.NFD_ERROR)
{
errorMessage = FromUtf8(NativeFunctions.NFD_GetError());
}
else if (result == nfdresult_t.NFD_OKAY)
{
var outPathNts = (byte*)outPathIntPtr.ToPointer();
path = FromUtf8(outPathNts);
NativeFunctions.NFD_Free(outPathIntPtr);
}
return new DialogResult(result, path, null, errorMessage);
}
}
public static unsafe DialogResult FileOpenMultiple(string filterList = null, string defaultPath = null)
{
fixed (byte* filterListNts = filterList != null ? ToUtf8(filterList) : null)
fixed (byte* defaultPathNts = defaultPath != null ? ToUtf8(defaultPath) : null)
{
List<string> paths = null;
string errorMessage = null;
nfdpathset_t pathSet;
var result = need32bit
? NativeFunctions32.NFD_OpenDialogMultiple(filterListNts, defaultPathNts, &pathSet)
: NativeFunctions.NFD_OpenDialogMultiple(filterListNts, defaultPathNts, &pathSet);
if (result == nfdresult_t.NFD_ERROR)
{
errorMessage = FromUtf8(NativeFunctions.NFD_GetError());
}
else if (result == nfdresult_t.NFD_OKAY)
{
var pathCount = (int)NativeFunctions.NFD_PathSet_GetCount(&pathSet).ToUInt32();
paths = new List<string>(pathCount);
for (int i = 0; i < pathCount; i++)
{
paths.Add(FromUtf8(NativeFunctions.NFD_PathSet_GetPath(&pathSet, new UIntPtr((uint)i))));
}
NativeFunctions.NFD_PathSet_Free(&pathSet);
}
return new DialogResult(result, null, paths, errorMessage);
}
}
}
public class DialogResult
{
private readonly nfdresult_t result;
public string Path { get; }
public IReadOnlyList<string> Paths { get; }
public bool IsError => result == nfdresult_t.NFD_ERROR;
public string ErrorMessage { get; }
public bool IsCancelled => result == nfdresult_t.NFD_CANCEL;
public bool IsOk => result == nfdresult_t.NFD_OKAY;
internal DialogResult(nfdresult_t result, string path, IReadOnlyList<string> paths, string errorMessage)
{
this.result = result;
Path = path;
Paths = paths;
ErrorMessage = errorMessage;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6ebb4f74b2d8f8a439ee20966bf2c60a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

8
linux-x64.meta Normal file
View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: eed29a6085c36bb4e98422a03a723358
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
linux-x64/native.meta Normal file
View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ea7476c68cb00074380caeb1b5261147
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

BIN
linux-x64/native/libnfd.so LFS Normal file

Binary file not shown.

View File

@@ -0,0 +1,63 @@
fileFormatVersion: 2
guid: 34eeac71b18853248a554a04ac9d0fe1
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
: Any
second:
enabled: 0
settings:
Exclude Editor: 0
Exclude Linux64: 0
Exclude OSXUniversal: 1
Exclude Win: 0
Exclude Win64: 0
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 1
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: AnyOS
- first:
Standalone: Linux64
second:
enabled: 1
settings:
CPU: AnyCPU
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Win
second:
enabled: 1
settings:
CPU: AnyCPU
- first:
Standalone: Win64
second:
enabled: 1
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

8
osx-x64.meta Normal file
View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 800cd214d76e3b14f9ec0c08a10d65ad
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
osx-x64/native.meta Normal file
View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b09d86f589ea1464bbda71d0bde80d07
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

BIN
osx-x64/native/libnfd.dylib LFS Normal file

Binary file not shown.

View File

@@ -0,0 +1,33 @@
fileFormatVersion: 2
guid: 88fc2d87305af8245b348321a9885752
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 1
settings:
DefaultValueInitialized: true
- first:
Standalone: OSXUniversal
second:
enabled: 1
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

7
package.json.meta Normal file
View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 8c9548a64f6c56446ae4936f8380cf55
PackageManifestImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
win-x64.meta Normal file
View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e6f7345fd4c1a27409c5cb5cbc2a3406
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
win-x64/native.meta Normal file
View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: bb7f01f6b699059408380233ae00ac65
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

BIN
win-x64/native/nfd.dll LFS Normal file

Binary file not shown.

View File

@@ -0,0 +1,63 @@
fileFormatVersion: 2
guid: 6ec1414486663964eb69885be027c2d0
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
: Any
second:
enabled: 0
settings:
Exclude Editor: 0
Exclude Linux64: 0
Exclude OSXUniversal: 0
Exclude Win: 1
Exclude Win64: 0
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 1
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: AnyOS
- first:
Standalone: Linux64
second:
enabled: 1
settings:
CPU: AnyCPU
- first:
Standalone: OSXUniversal
second:
enabled: 1
settings:
CPU: AnyCPU
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Win64
second:
enabled: 1
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

8
win-x86.meta Normal file
View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6de4d879e29af464ca9ab980d6d4f14a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
win-x86/native.meta Normal file
View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6288284b9e159154b9cd99d3c6256ff1
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

BIN
win-x86/native/nfd.dll LFS Normal file

Binary file not shown.

View File

@@ -0,0 +1,63 @@
fileFormatVersion: 2
guid: 15bd6a4d8a53d204dbae30647541ed30
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
: Any
second:
enabled: 0
settings:
Exclude Editor: 1
Exclude Linux64: 0
Exclude OSXUniversal: 0
Exclude Win: 0
Exclude Win64: 1
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: AnyOS
- first:
Standalone: Linux64
second:
enabled: 1
settings:
CPU: AnyCPU
- first:
Standalone: OSXUniversal
second:
enabled: 1
settings:
CPU: AnyCPU
- first:
Standalone: Win
second:
enabled: 1
settings:
CPU: AnyCPU
- first:
Standalone: Win64
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant: