diff --git a/src/DotRecast.Recast.Demo/DotRecast.Recast.Demo.csproj b/src/DotRecast.Recast.Demo/DotRecast.Recast.Demo.csproj
index 39e9fd4..65de201 100644
--- a/src/DotRecast.Recast.Demo/DotRecast.Recast.Demo.csproj
+++ b/src/DotRecast.Recast.Demo/DotRecast.Recast.Demo.csproj
@@ -7,18 +7,18 @@
-
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/src/DotRecast.Recast.Demo/Settings/RcSettingsView.cs b/src/DotRecast.Recast.Demo/Settings/RcSettingsView.cs
index cb97610..c70c17f 100644
--- a/src/DotRecast.Recast.Demo/Settings/RcSettingsView.cs
+++ b/src/DotRecast.Recast.Demo/Settings/RcSettingsView.cs
@@ -16,8 +16,8 @@ freely, subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
-using System.Linq;
-using System.Numerics;
+using System;
+using System.IO;
using DotRecast.Core;
using DotRecast.Recast.Demo.Draw;
using DotRecast.Recast.Demo.UI;
@@ -85,7 +85,25 @@ public class RcSettingsView : IRcView
bool mouseInside = false;
ImGui.Text("Input Mesh");
ImGui.Separator();
- ImGui.Button("Load Source Geom...");
+
+ const string strLoadSourceGeom = "Load Source Geom...";
+ if (ImGui.Button(strLoadSourceGeom))
+ {
+ ImGui.OpenPopup(strLoadSourceGeom);
+ }
+
+ bool loadSourceGeomPopup = true;
+ if (ImGui.BeginPopupModal(strLoadSourceGeom, ref loadSourceGeomPopup, ImGuiWindowFlags.NoTitleBar))
+ {
+ var picker = ImFilePicker.GetFilePicker(strLoadSourceGeom, Path.Combine(Environment.CurrentDirectory));
+ if (picker.Draw())
+ {
+ Console.WriteLine(picker.SelectedFile);
+ ImFilePicker.RemoveFilePicker(strLoadSourceGeom);
+ }
+ ImGui.EndPopup();
+ }
+
ImGui.Text($"Verts: {voxels[0]} Tris: {voxels[1]}");
ImGui.NewLine();
@@ -120,7 +138,7 @@ public class RcSettingsView : IRcView
ImGui.RadioButton(label, ref _partitioning, partition.Idx);
});
ImGui.NewLine();
-
+
ImGui.Text("Filtering");
ImGui.Separator();
ImGui.Checkbox("Low Hanging Obstacles", ref filterLowHangingObstacles);
@@ -159,8 +177,24 @@ public class RcSettingsView : IRcView
ImGui.Text($"Build Time: {buildTime} ms");
ImGui.Separator();
buildTriggered = ImGui.Button("Build");
- ImGui.SameLine();
- navMeshInputTrigerred = ImGui.Button("Load Nav Mesh...");
+ const string strLoadNavMesh = "Load Nav Mesh...";
+ if (ImGui.Button(strLoadNavMesh))
+ {
+ ImGui.OpenPopup(strLoadNavMesh);
+ }
+
+ bool isLoadNavMesh = true;
+ if (ImGui.BeginPopupModal(strLoadNavMesh, ref isLoadNavMesh, ImGuiWindowFlags.NoTitleBar))
+ {
+ var picker = ImFilePicker.GetFilePicker(strLoadNavMesh, Path.Combine(Environment.CurrentDirectory));
+ if (picker.Draw())
+ {
+ Console.WriteLine(picker.SelectedFile);
+ ImFilePicker.RemoveFilePicker(strLoadNavMesh);
+ }
+ ImGui.EndPopup();
+ }
+
ImGui.NewLine();
ImGui.Text("Draw");
diff --git a/src/DotRecast.Recast.Demo/UI/ImFilePicker.cs b/src/DotRecast.Recast.Demo/UI/ImFilePicker.cs
new file mode 100644
index 0000000..522dede
--- /dev/null
+++ b/src/DotRecast.Recast.Demo/UI/ImFilePicker.cs
@@ -0,0 +1,186 @@
+using System;
+using System.Numerics;
+using System.Collections.Generic;
+using System.Drawing;
+using System.IO;
+using ImGuiNET;
+
+namespace DotRecast.Recast.Demo.UI;
+
+// original code : https://gist.github.com/prime31/91d1582624eb2635395417393018016e
+public class ImFilePicker
+{
+ private static readonly Dictionary _filePickers = new Dictionary();
+
+ public string RootFolder;
+ public string CurrentFolder;
+ public string SelectedFile;
+ public List AllowedExtensions;
+ public bool OnlyAllowFolders;
+
+ public static ImFilePicker GetFolderPicker(string pickerName, string startingPath)
+ => GetFilePicker(pickerName, startingPath, null, true);
+
+ public static ImFilePicker GetFilePicker(string pickerName, string startingPath, string searchFilter = null, bool onlyAllowFolders = false)
+ {
+ if (File.Exists(startingPath))
+ {
+ startingPath = new FileInfo(startingPath).DirectoryName;
+ }
+ else if (string.IsNullOrEmpty(startingPath) || !Directory.Exists(startingPath))
+ {
+ startingPath = Environment.CurrentDirectory;
+ if (string.IsNullOrEmpty(startingPath))
+ startingPath = AppContext.BaseDirectory;
+ }
+
+ if (!_filePickers.TryGetValue(pickerName, out ImFilePicker fp))
+ {
+ fp = new ImFilePicker();
+ fp.RootFolder = startingPath;
+ fp.CurrentFolder = startingPath;
+ fp.OnlyAllowFolders = onlyAllowFolders;
+
+ if (searchFilter != null)
+ {
+ if (fp.AllowedExtensions != null)
+ fp.AllowedExtensions.Clear();
+ else
+ fp.AllowedExtensions = new List();
+
+ fp.AllowedExtensions.AddRange(searchFilter.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries));
+ }
+
+ _filePickers.Add(pickerName, fp);
+ }
+
+ return fp;
+ }
+
+ public static void RemoveFilePicker(string pickerName) => _filePickers.Remove(pickerName);
+
+ public bool Draw()
+ {
+ ImGui.Text("Current Folder: " + CurrentFolder);
+ bool result = false;
+
+ if (ImGui.BeginChildFrame(1, new Vector2(1024, 400)))
+ {
+ var di = new DirectoryInfo(CurrentFolder);
+ if (di.Exists)
+ {
+ if (di.Parent != null)
+ {
+ ImGui.PushStyleColor(ImGuiCol.Text, (uint)Color.Yellow.ToArgb());
+ if (ImGui.Selectable("../", false, ImGuiSelectableFlags.DontClosePopups))
+ CurrentFolder = di.Parent.FullName;
+
+ ImGui.PopStyleColor();
+ }
+
+ var fileSystemEntries = GetFileSystemEntries(di.FullName);
+ foreach (var fse in fileSystemEntries)
+ {
+ if (Directory.Exists(fse))
+ {
+ var name = Path.GetFileName(fse);
+ ImGui.PushStyleColor(ImGuiCol.Text, (uint)Color.Yellow.ToArgb());
+ if (ImGui.Selectable(name + "/", false, ImGuiSelectableFlags.DontClosePopups))
+ CurrentFolder = fse;
+ ImGui.PopStyleColor();
+ }
+ else
+ {
+ var name = Path.GetFileName(fse);
+ bool isSelected = SelectedFile == fse;
+ if (ImGui.Selectable(name, isSelected, ImGuiSelectableFlags.DontClosePopups))
+ SelectedFile = fse;
+
+ if (ImGui.IsMouseDoubleClicked(0))
+ {
+ result = true;
+ ImGui.CloseCurrentPopup();
+ }
+ }
+ }
+ }
+ }
+
+ ImGui.EndChildFrame();
+
+
+ if (ImGui.Button("Cancel"))
+ {
+ result = false;
+ ImGui.CloseCurrentPopup();
+ }
+
+ if (OnlyAllowFolders)
+ {
+ ImGui.SameLine();
+ if (ImGui.Button("Open"))
+ {
+ result = true;
+ SelectedFile = CurrentFolder;
+ ImGui.CloseCurrentPopup();
+ }
+ }
+ else if (SelectedFile != null)
+ {
+ ImGui.SameLine();
+ if (ImGui.Button("Open"))
+ {
+ result = true;
+ ImGui.CloseCurrentPopup();
+ }
+ }
+
+ return result;
+ }
+
+ bool TryGetFileInfo(string fileName, out FileInfo realFile)
+ {
+ try
+ {
+ realFile = new FileInfo(fileName);
+ return true;
+ }
+ catch
+ {
+ realFile = null;
+ return false;
+ }
+ }
+
+ List GetFileSystemEntries(string fullName)
+ {
+ var files = new List();
+ var dirs = new List();
+
+ foreach (var fse in Directory.GetFileSystemEntries(fullName, ""))
+ {
+ if (Directory.Exists(fse))
+ {
+ dirs.Add(fse);
+ }
+ else if (!OnlyAllowFolders)
+ {
+ if (AllowedExtensions != null)
+ {
+ var ext = Path.GetExtension(fse);
+ if (AllowedExtensions.Contains(ext))
+ files.Add(fse);
+ }
+ else
+ {
+ files.Add(fse);
+ }
+ }
+ }
+
+ var ret = new List(dirs);
+ ret.AddRange(files);
+
+ return ret;
+ }
+}
\ No newline at end of file