using System.Collections.Generic; using System.IO; using System.Linq; using Godot; using Learn.Models; public partial class LearnTree : Tree { [Export] private FileDirSelector _dirSelector; [Export] private ItemInfoPanel _itemInfoPanel; private bool _updateItemInfoPanel; private readonly HashSet _selectingNodes = new (); private readonly Dictionary _mapper = new(); public override void _Ready() { MultiSelected += OnMultiSelected; } public override void _Process(double delta) { if (_updateItemInfoPanel) { _updateItemInfoPanel = false; _itemInfoPanel.SetSelectedNodes(_selectingNodes); } } private void OnMultiSelected(TreeItem item, long column, bool selected) { if(selected) _selectingNodes.Add(_mapper[item]); else _selectingNodes.Remove(_mapper[item]); _updateItemInfoPanel = true; } 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; } 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)); } } } private async void Open() { var path = await _dirSelector.SelectFolderAsync() ?? "None"; if (string.IsNullOrEmpty(path)) return; Clear(); _mapper.Clear(); _selectingNodes.Clear(); TreeItem root = CreateItem(); BuildTree(root, path); _updateItemInfoPanel = true; } }