Files
crtr/Assets/Cryville/Common/Unity/FileDialog.cs
2023-03-26 23:25:20 +08:00

148 lines
4.4 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.UI;
namespace Cryville.Common.Unity {
public class FileDialog : MonoBehaviour {
Transform panel;
Transform title;
Transform drives;
Transform dirs;
Transform files;
public event Action OnClose;
#if UNITY_ANDROID && !UNITY_EDITOR_WIN
string androidStorage = "";
#endif
string fileName = null;
public string FileName {
get { return fileName; }
}
public string[] m_filter = new string[]{};
public string[] Filter {
set { m_filter = value; }
}
public IReadOnlyDictionary<string, string> m_presetPaths = new Dictionary<string, string>();
public IReadOnlyDictionary<string, string> PresetPaths {
get { return m_presetPaths; }
set { m_presetPaths = value; }
}
GameObject prefabButton;
void Start() {
prefabButton = Resources.Load<GameObject>("Common/Button");
panel = gameObject.transform.Find("Panel");
title = panel.Find("Title/Text");
drives = panel.Find("Drives/DrivesInner");
dirs = panel.Find("Directories/DirectoriesInner");
files = panel.Find("Files/FilesInner");
if (CurrentDirectory == null) {
#if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN
CurrentDirectory = new DirectoryInfo(Directory.GetCurrentDirectory());
#elif UNITY_ANDROID
using (AndroidJavaClass ajc = new AndroidJavaClass("android.os.Environment"))
using (AndroidJavaObject file = ajc.CallStatic<AndroidJavaObject>("getExternalStorageDirectory")) {
androidStorage = file.Call<string>("getAbsolutePath");
CurrentDirectory = new DirectoryInfo(androidStorage);
}
#else
#error No default directory
#endif
}
UpdateGUI(0);
}
public void Show() {
fileName = null;
gameObject.SetActive(true);
}
public void Close() {
var ev = OnClose;
if (ev != null) ev.Invoke();
gameObject.SetActive(false);
}
public DirectoryInfo CurrentDirectory;
void ChangeDirectory(DirectoryInfo s) {
CurrentDirectory = s;
UpdateGUI(1);
}
void SelectFile(string s) {
fileName = s;
Close();
}
void UpdateGUI(int depth) {
title.GetComponent<Text>().text = CurrentDirectory.FullName;
if (depth <= 0) {
CallHelper.Purge(drives);
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
var dl = Directory.GetLogicalDrives();
foreach (string d in dl) {
GameObject btn = Instantiate(prefabButton);
btn.GetComponentInChildren<Text>().text = d;
btn.GetComponentInChildren<Button>().onClick.AddListener(() => ChangeDirectory(new DirectoryInfo(d)));
btn.transform.SetParent(drives, false);
}
#elif UNITY_ANDROID
GameObject sbtn = GameObject.Instantiate<GameObject>(prefabButton);
sbtn.GetComponentInChildren<Text>().text = "Storage";
sbtn.GetComponentInChildren<Button>().onClick.AddListener(() => ChangeDirectory(new DirectoryInfo(androidStorage)));
sbtn.transform.SetParent(drives, false);
#else
#error No update GUI logic
#endif
foreach (var p in m_presetPaths) {
var d = new DirectoryInfo(p.Value);
if (d.Exists) {
GameObject btn = Instantiate(prefabButton);
btn.GetComponentInChildren<Text>().text = p.Key;
btn.GetComponentInChildren<Button>().onClick.AddListener(() => ChangeDirectory(d));
btn.transform.SetParent(drives, false);
}
}
}
CallHelper.Purge(dirs);
DirectoryInfo[] subdirs = CurrentDirectory.GetDirectories();
GameObject pbtn = Instantiate(prefabButton);
pbtn.GetComponentInChildren<Text>().text = "..";
pbtn.GetComponentInChildren<Button>().onClick.AddListener(() => ChangeDirectory(new DirectoryInfo(Path.Combine(CurrentDirectory.FullName, ".."))));
pbtn.transform.SetParent(dirs, false);
foreach (DirectoryInfo d in subdirs) {
GameObject btn = Instantiate(prefabButton);
btn.GetComponentInChildren<Text>().text = d.Name;
var ts = d;
btn.GetComponentInChildren<Button>().onClick.AddListener(() => ChangeDirectory(ts));
btn.transform.SetParent(dirs, false);
}
CallHelper.Purge(files);
FileInfo[] fl = CurrentDirectory.GetFiles();
foreach (FileInfo d in fl) {
foreach (string ext in m_filter) {
if (d.Extension == ext) {
GameObject btn = Instantiate(prefabButton);
btn.GetComponentInChildren<Text>().text = d.Name + " / " + (d.Length / 1024.0).ToString("0.0 KiB");
var ts = d.FullName;
btn.GetComponentInChildren<Button>().onClick.AddListener(() => SelectFile(ts));
btn.transform.SetParent(files, false);
break;
}
}
}
}
}
}