using System.Collections.Generic; using System.IO; using Godot; using Learn.Models; public partial class LearnTree : Tree { [Export] private FileDirSelector _dirSelector; public override void _Ready() { ItemSelected += OnItemSelected; } private void OnItemSelected() { TreeItem selected = GetSelected(); if (selected != null) { GD.Print($"选中了: {selected.GetText(0)}"); } } private void Setup() { // 1. 设置列数 Columns = 2; // 设置标题 (需要在属性面板开启 Column Title Visible,或者代码开启) SetColumnTitle(0, "角色 (Role)"); SetColumnTitle(1, "状态 (Status)"); SetColumnTitlesVisible(true); // 2. 创建根节点 (Root) // CreateItem() 不传参数即为根节点 TreeItem root = CreateItem(); root.SetText(0, "所有单位"); // 3. 创建子节点 // 传入父节点作为参数 TreeItem warrior = CreateItem(root); warrior.SetText(0, "战士"); warrior.SetText(1, "HP: 100"); // 4. 创建层级更深的节点 TreeItem sword = CreateItem(warrior); sword.SetText(0, "铁剑"); sword.SetText(1, "攻击力: 12"); } private readonly Dictionary _mapper = new(); 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"; return item; } private void BuildTree(TreeItem root, string path) { var nodes = new Stack<(TreeItem node, string path)>(); nodes.Push((root, path)); while (nodes.Count > 0) { var node = nodes.Pop(); foreach (var filePath in Directory.GetFiles(node.path)) { var item = InitItem(filePath, false); var chNode = CreateNode(node.node, item); _mapper[chNode] = item; } foreach (var subDirPath in Directory.GetDirectories(node.path)) { var item = InitItem(subDirPath, true); var chNode = CreateNode(node.node, item); _mapper[chNode] = item; nodes.Push((chNode, subDirPath)); } } } private async void Open() { var path = await _dirSelector.SelectFolderAsync() ?? "None"; if (string.IsNullOrEmpty(path)) return; Clear(); _mapper.Clear(); TreeItem root = CreateItem(); BuildTree(root, path); } }