using System.Collections.Generic; using System.IO; using Godot; using Learn.Models; namespace Learn.Component; public partial class MainTreePanel : Tree { private readonly HashSet _columns = new(); private readonly HashSet _selectingNodes = new (); private readonly Dictionary _mapper = new(); public HashSet SelectingNodes => _selectingNodes; public override void _Ready() { Columns = 1; SetColumnTitlesVisible(true); SetColumnTitle(0, "文件名"); SetColumnCustomMinimumWidth(0, 400); SetColumnExpand(0, true); MultiSelected += OnMultiSelected; } public void AddColumn(string columnName) { if (string.IsNullOrEmpty(columnName)) return; _columns.Add(columnName); UpdateColumns(); } public void RemoveColumn(string columnName) { if (string.IsNullOrEmpty(columnName)) return; _columns.Remove(columnName); UpdateColumns(); } public void UpdateColumns() { Columns = _columns.Count + 1; int index = 1; foreach (var column in _columns) { SetColumnTitle(index, column); SetColumnCustomMinimumWidth(index, 200); SetColumnExpand(index, true); index += 1; } foreach (var kv in _mapper) { index = 1; foreach (var column in _columns) { if (kv.Value.TryGetValue(column, out var value, out _)) { kv.Key.SetText(index, value); } else { kv.Key.SetText(index, ""); } index += 1; } } } private void OnMultiSelected(TreeItem item, long column, bool selected) { if(selected) _selectingNodes.Add(_mapper[item]); else _selectingNodes.Remove(_mapper[item]); } private TreeItem CreateNode(TreeItem father, Item item) { var node = CreateItem(father); node.SetText(0, item.Info["Name"]); return node; } private Item InitItem(string path, bool isDir) { var name = Path.GetFileName(path); var item = new Item(); item.Info["Name"] = name; item.Info["IsDir"] = isDir ? "True" : "False"; item.Info["Path"] = path; return item; } public void Build(string path) { Clear(); _mapper.Clear(); _selectingNodes.Clear(); TreeItem root = CreateItem(); BuildTree(root, path); } private void BuildTree(TreeItem root, string path) { var nodes = new Stack<(TreeItem node, string path)>(); _mapper[root] = new TreeNode(null); nodes.Push((root, path)); while (nodes.Count > 0) { var node = nodes.Pop(); var father = node.node; var fatherNode = _mapper[father]; foreach (var filePath in Directory.GetFiles(node.path)) { var item = InitItem(filePath, false); var childNode = new TreeNode(item); fatherNode.AddNode(childNode); var child = CreateNode(father, item); _mapper[child] = childNode; } foreach (var subDirPath in Directory.GetDirectories(node.path)) { var item = InitItem(subDirPath, true); var childNode = new TreeNode(item); fatherNode.AddNode(childNode); var child = CreateNode(father, item); _mapper[child] = childNode; nodes.Push((child, subDirPath)); } } } }