Skip to content

Instantly share code, notes, and snippets.

@jeang-bo-yuan
Forked from prime31/FilePicker.cs
Last active January 13, 2026 09:25
Show Gist options
  • Select an option

  • Save jeang-bo-yuan/6134120fcfb202606d725630a35ac1bc to your computer and use it in GitHub Desktop.

Select an option

Save jeang-bo-yuan/6134120fcfb202606d725630a35ac1bc to your computer and use it in GitHub Desktop.
Simple file and folder picker for ImGui.Net + uimgui(https://github.com/psydack/uimgui.git
/// Reference: https://gist.github.com/prime31/91d1582624eb2635395417393018016e
using ImGuiNET;
using System;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
namespace Nez.ImGuiTools
{
public class FilePicker
{
static readonly Dictionary<object, FilePicker> _filePickers = new Dictionary<object, FilePicker>();
public string RootFolder;
public string CurrentFolder;
public string SelectedFile;
public List<string> AllowedExtensions;
public bool OnlyAllowFolders;
public static FilePicker GetFolderPicker(object o, string startingPath)
=> GetFilePicker(o, startingPath, null, true);
public static FilePicker GetFilePicker(object o, 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(o, out FilePicker fp))
{
fp = new FilePicker();
fp.RootFolder = startingPath;
fp.CurrentFolder = startingPath;
fp.OnlyAllowFolders = onlyAllowFolders;
if (searchFilter != null)
{
if (fp.AllowedExtensions != null)
fp.AllowedExtensions.Clear();
else
fp.AllowedExtensions = new List<string>();
fp.AllowedExtensions.AddRange(searchFilter.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries));
}
_filePickers.Add(o, fp);
}
return fp;
}
public static void RemoveFilePicker(object o) => _filePickers.Remove(o);
/// <summary>
/// MODIFY: return true -> close
/// </summary>
/// <returns></returns>
public bool Draw()
{
ImGui.Text("Current Folder: " + Path.GetRelativePath(RootFolder, CurrentFolder));
bool result = false;
if (ImGui.BeginChild("Content", new Vector2(400, 400)))
{
var di = new DirectoryInfo(CurrentFolder);
if (di.Exists)
{
if (di.Parent != null && CurrentFolder != RootFolder)
{
ImGui.PushStyleColor(ImGuiCol.Text, Color.yellow);
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, Color.yellow);
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.EndChild();
if (ImGui.Button("Cancel"))
{
result = true;
SelectedFile = null;
//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();
}
}
if (SelectedFile != null)
ImGui.TextWrapped("Selected:" + SelectedFile);
return result;
}
bool TryGetFileInfo(string fileName, out FileInfo realFile)
{
try
{
realFile = new FileInfo(fileName);
return true;
}
catch
{
realFile = null;
return false;
}
}
List<string> GetFileSystemEntries(string fullName)
{
var files = new List<string>();
var dirs = new List<string>();
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<string>(dirs);
ret.AddRange(files);
return ret;
}
}
}
var isOpen = true;
if (isOpen && ImGui.Begin("Read Text"))
{
var picker = FilePicker.GetFilePicker(this, Application.streamingAssetsPath, searchFilter: ".txt");
if (picker.Draw())
{
var path = picker.SelectedFile;
Debug.Log(path);
// do something...
isOpen = false;
FilePicker.RemoveFilePicker(this); // You can remove this line, if you want to open dialog from same place next time
}
ImGui.End();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment