LearnGodot/Component/NodeInfoEditPanel.cs
2025-12-28 23:31:18 +08:00

129 lines
2.7 KiB
C#

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<TreeNode> _nodes;
private ItemGroup _itemGroup;
private readonly Dictionary<TreeItem, string> _nodeKeys = new ();
private readonly HashSet<TreeItem> _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<TreeNode> 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();
}
}