331 lines
9.8 KiB
C#
331 lines
9.8 KiB
C#
using System;
|
|
using System.IO;
|
|
using TMPro;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
/// <summary>
|
|
/// 文件选择对话框
|
|
/// 提供文件选择和保存功能
|
|
/// </summary>
|
|
public class FileSelectionDialog : BasePanel
|
|
{
|
|
[Header("UI组件")]
|
|
public TextMeshProUGUI TitleText;
|
|
public TMP_InputField FilePathInput; // 文件路径输入框
|
|
public Button BrowseButton; // 浏览按钮
|
|
public Button ConfirmButton; // 确认按钮
|
|
public Button CancelButton; // 取消按钮
|
|
public TMP_Dropdown FileTypeDropdown; // 文件类型下拉框
|
|
|
|
[Header("文件浏览")]
|
|
public ScrollRect DirectoryScrollRect; // 目录滚动视图
|
|
public Transform DirectoryContent; // 目录内容容器
|
|
public GameObject DirectoryItemPrefab; // 目录项预制体
|
|
public GameObject FileItemPrefab; // 文件项预制体
|
|
|
|
private Action<string> _onConfirm;
|
|
private Action _onCancel;
|
|
private string _currentDirectory = Application.streamingAssetsPath;
|
|
private string[] _fileFilters;
|
|
private bool _isSaveMode;
|
|
private string _defaultFileName;
|
|
|
|
public override void Init()
|
|
{
|
|
InitializeButtons();
|
|
_currentDirectory = Application.streamingAssetsPath;
|
|
RefreshDirectoryView();
|
|
}
|
|
|
|
private void InitializeButtons()
|
|
{
|
|
if (BrowseButton != null)
|
|
{
|
|
BrowseButton.onClick.AddListener(OnBrowseClicked);
|
|
}
|
|
|
|
if (ConfirmButton != null)
|
|
{
|
|
ConfirmButton.onClick.AddListener(OnConfirmClicked);
|
|
}
|
|
|
|
if (CancelButton != null)
|
|
{
|
|
CancelButton.onClick.AddListener(OnCancelClicked);
|
|
}
|
|
|
|
if (FileTypeDropdown != null)
|
|
{
|
|
FileTypeDropdown.onValueChanged.AddListener(OnFileTypeChanged);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 显示文件选择对话框
|
|
/// </summary>
|
|
public static void Show(string title, string fileFilter, Action<string> onConfirm, Action onCancel = null)
|
|
{
|
|
var dialog = EnhancedUIManager.Instance.ShowPanel<FileSelectionDialog>(UIPanelType.Dialog, true, true);
|
|
if (dialog != null)
|
|
{
|
|
dialog.ShowFileDialog(title, fileFilter, false, "", onConfirm, onCancel);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 显示文件保存对话框
|
|
/// </summary>
|
|
public static void ShowSave(string title, string fileFilter, string defaultFileName, Action<string> onConfirm, Action onCancel = null)
|
|
{
|
|
var dialog = EnhancedUIManager.Instance.ShowPanel<FileSelectionDialog>(UIPanelType.Dialog, true, true);
|
|
if (dialog != null)
|
|
{
|
|
dialog.ShowFileDialog(title, fileFilter, true, defaultFileName, onConfirm, onCancel);
|
|
}
|
|
}
|
|
|
|
private void ShowFileDialog(string title, string fileFilter, bool isSaveMode, string defaultFileName, Action<string> onConfirm, Action onCancel)
|
|
{
|
|
_onConfirm = onConfirm;
|
|
_onCancel = onCancel;
|
|
_isSaveMode = isSaveMode;
|
|
_defaultFileName = defaultFileName;
|
|
|
|
if (TitleText != null)
|
|
{
|
|
TitleText.text = title;
|
|
}
|
|
|
|
SetupFileFilters(fileFilter);
|
|
|
|
if (_isSaveMode && !string.IsNullOrEmpty(_defaultFileName))
|
|
{
|
|
if (FilePathInput != null)
|
|
{
|
|
FilePathInput.text = Path.Combine(_currentDirectory, _defaultFileName);
|
|
}
|
|
}
|
|
|
|
RefreshDirectoryView();
|
|
}
|
|
|
|
private void SetupFileFilters(string fileFilter)
|
|
{
|
|
if (FileTypeDropdown != null)
|
|
{
|
|
FileTypeDropdown.options.Clear();
|
|
|
|
if (string.IsNullOrEmpty(fileFilter))
|
|
{
|
|
FileTypeDropdown.options.Add(new TMP_Dropdown.OptionData("所有文件 (*.*)", null));
|
|
_fileFilters = new string[] { "*.*" };
|
|
}
|
|
else
|
|
{
|
|
// 解析文件过滤器 "描述|*.ext;*.ext2|描述2|*.ext3"
|
|
string[] parts = fileFilter.Split('|');
|
|
_fileFilters = new string[parts.Length / 2];
|
|
|
|
for (int i = 0; i < parts.Length; i += 2)
|
|
{
|
|
if (i + 1 < parts.Length)
|
|
{
|
|
string description = parts[i];
|
|
string extensions = parts[i + 1];
|
|
|
|
FileTypeDropdown.options.Add(new TMP_Dropdown.OptionData(description, null));
|
|
_fileFilters[i / 2] = extensions;
|
|
}
|
|
}
|
|
}
|
|
|
|
FileTypeDropdown.value = 0;
|
|
FileTypeDropdown.RefreshShownValue();
|
|
}
|
|
}
|
|
|
|
private void RefreshDirectoryView()
|
|
{
|
|
if (DirectoryContent == null) return;
|
|
|
|
// 清空现有项目
|
|
foreach (Transform child in DirectoryContent)
|
|
{
|
|
Destroy(child.gameObject);
|
|
}
|
|
|
|
try
|
|
{
|
|
// 添加返回上级目录项
|
|
var parentDir = Directory.GetParent(_currentDirectory);
|
|
if (parentDir != null)
|
|
{
|
|
CreateDirectoryItem("..", parentDir.FullName, true);
|
|
}
|
|
|
|
// 添加子目录
|
|
string[] directories = Directory.GetDirectories(_currentDirectory);
|
|
foreach (string dir in directories)
|
|
{
|
|
string dirName = Path.GetFileName(dir);
|
|
CreateDirectoryItem(dirName, dir, false);
|
|
}
|
|
|
|
// 添加文件
|
|
string[] files = Directory.GetFiles(_currentDirectory);
|
|
foreach (string file in files)
|
|
{
|
|
if (IsFileMatchFilter(file))
|
|
{
|
|
string fileName = Path.GetFileName(file);
|
|
CreateFileItem(fileName, file);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.LogError($"刷新目录视图失败: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
private bool IsFileMatchFilter(string filePath)
|
|
{
|
|
if (_fileFilters == null || _fileFilters.Length == 0) return true;
|
|
|
|
string selectedFilter = _fileFilters[FileTypeDropdown?.value ?? 0];
|
|
if (selectedFilter == "*.*") return true;
|
|
|
|
string[] extensions = selectedFilter.Split(';');
|
|
string fileExtension = Path.GetExtension(filePath).ToLower();
|
|
|
|
foreach (string ext in extensions)
|
|
{
|
|
string filterExt = ext.Replace("*", "").ToLower();
|
|
if (fileExtension == filterExt) return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private void CreateDirectoryItem(string name, string path, bool isParent)
|
|
{
|
|
if (DirectoryItemPrefab == null) return;
|
|
|
|
var item = Instantiate(DirectoryItemPrefab, DirectoryContent);
|
|
var text = item.GetComponentInChildren<TextMeshProUGUI>();
|
|
if (text != null)
|
|
{
|
|
text.text = isParent ? ".. (上级目录)" : $"[{name}]";
|
|
}
|
|
|
|
var button = item.GetComponent<Button>();
|
|
if (button != null)
|
|
{
|
|
button.onClick.AddListener(() => {
|
|
_currentDirectory = path;
|
|
RefreshDirectoryView();
|
|
UpdatePathInput();
|
|
});
|
|
}
|
|
}
|
|
|
|
private void CreateFileItem(string name, string path)
|
|
{
|
|
if (FileItemPrefab == null) return;
|
|
|
|
var item = Instantiate(FileItemPrefab, DirectoryContent);
|
|
var text = item.GetComponentInChildren<TextMeshProUGUI>();
|
|
if (text != null)
|
|
{
|
|
text.text = name;
|
|
}
|
|
|
|
var button = item.GetComponent<Button>();
|
|
if (button != null)
|
|
{
|
|
button.onClick.AddListener(() => {
|
|
if (FilePathInput != null)
|
|
{
|
|
FilePathInput.text = path;
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
private void UpdatePathInput()
|
|
{
|
|
if (FilePathInput != null)
|
|
{
|
|
if (_isSaveMode && !string.IsNullOrEmpty(_defaultFileName))
|
|
{
|
|
FilePathInput.text = Path.Combine(_currentDirectory, _defaultFileName);
|
|
}
|
|
else
|
|
{
|
|
FilePathInput.text = _currentDirectory;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void OnBrowseClicked()
|
|
{
|
|
// 这里可以集成系统文件对话框,如果有需要的话
|
|
Debug.Log("打开系统文件选择对话框");
|
|
}
|
|
|
|
private void OnConfirmClicked()
|
|
{
|
|
string selectedPath = FilePathInput?.text ?? "";
|
|
|
|
if (string.IsNullOrEmpty(selectedPath))
|
|
{
|
|
ConfirmDialog.Show("提示", "请选择或输入文件路径", () => { });
|
|
return;
|
|
}
|
|
|
|
if (_isSaveMode)
|
|
{
|
|
// 保存模式:检查目录是否存在
|
|
string directory = Path.GetDirectoryName(selectedPath);
|
|
if (!Directory.Exists(directory))
|
|
{
|
|
ConfirmDialog.Show("错误", "目录不存在", () => { });
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// 打开模式:检查文件是否存在
|
|
if (!File.Exists(selectedPath))
|
|
{
|
|
ConfirmDialog.Show("错误", "文件不存在", () => { });
|
|
return;
|
|
}
|
|
}
|
|
|
|
_onConfirm?.Invoke(selectedPath);
|
|
CloseDialog();
|
|
}
|
|
|
|
private void OnCancelClicked()
|
|
{
|
|
_onCancel?.Invoke();
|
|
CloseDialog();
|
|
}
|
|
|
|
private void OnFileTypeChanged(int index)
|
|
{
|
|
RefreshDirectoryView();
|
|
}
|
|
|
|
private void CloseDialog()
|
|
{
|
|
EnhancedUIManager.Instance.HidePanel<FileSelectionDialog>(true);
|
|
}
|
|
|
|
protected override void OnBackButtonPressed()
|
|
{
|
|
OnCancelClicked();
|
|
}
|
|
} |