using System; using System.Collections.Generic; using System.Linq; using Godot; using Learn.Models; namespace Learn.Component; public partial class NodeInfoEditPanel : Tree { public event Action OnNodeInfoEdited; private IEnumerable _nodes; private ItemGroup _itemGroup; private readonly Dictionary _nodeKeys = new (); private readonly HashSet _selectingNodes = new (); #region Columns Definitions private const int KeyColumn = 0; private const int ValueColumn = 1; #endregion public override void _Ready() { Columns = 2; SetColumnTitlesVisible(true); SetColumnTitle(KeyColumn, "键"); SetColumnCustomMinimumWidth(KeyColumn, 100); SetColumnExpand(KeyColumn, false); SetColumnTitle(ValueColumn, "值"); SetColumnExpand(ValueColumn, true); ItemEdited += OnItemEdited; MultiSelected += OnMultiSelected; } private void OnMultiSelected(TreeItem item, long column, bool selected) { for (int i = 0; i < Columns; i++) { if (i == column ? selected : item.IsSelected(i)) { _selectingNodes.Add(item); return; } } _selectingNodes.Remove(item); } private void OnItemEdited() { var node = GetEdited(); var prevKey = _nodeKeys[node]; var currentKey = node.GetText(KeyColumn); var value = node.GetText(ValueColumn); if (prevKey != currentKey) { _itemGroup.Remove(prevKey); } _itemGroup.SetValue(currentKey, value); OnNodeInfoEdited?.Invoke(); } public void SetNodes(IEnumerable nodes) { if (nodes == null) { _nodes = null; _itemGroup = null; } else { _nodes = nodes; _itemGroup = new ItemGroup(_nodes.Select(node => node.Info).ToList()); } OnNodesChanged(); } public void OnNodesChanged() { Clear(); _nodeKeys.Clear(); _selectingNodes.Clear(); if (_itemGroup == null) return; var root = CreateItem(); foreach (var key in _itemGroup.GetKeys()) { if(!_itemGroup.TryGetValue(key, out var value, out var isSame)) continue; var node = CreateItem(root); node.SetText(KeyColumn, key); node.SetText(ValueColumn, isSame ? value : "-"); node.SetEditable(KeyColumn, true); node.SetEditable(ValueColumn, true); _nodeKeys.Add(node, key); } OnNodeInfoEdited?.Invoke(); } public void AddKeyValue() { if(_itemGroup == null) return; var newFieldName = "newField"; int index = 0; while (!_itemGroup.TryAdd(newFieldName + (index == 0 ? "" : index.ToString()), "")) { index += 1; } OnNodesChanged(); } public void RemoveKeyValue() { if(_itemGroup == null) return; var root = GetRoot(); foreach (var node in _selectingNodes) { _itemGroup.Remove(_nodeKeys[node]); root.RemoveChild(node); } _selectingNodes.Clear(); OnNodeInfoEdited?.Invoke(); } }