This commit is contained in:
fengfeng 2025-12-15 18:32:57 +08:00
parent ce70970eda
commit 81d515e40b
4 changed files with 114 additions and 17 deletions

View File

@ -1,10 +1,11 @@
using System.Linq;
using Godot; using Godot;
using Godot.Collections; using Godot.Collections;
using Learn.Models; using Learn.Models;
public partial class ItemInfoPanel : Tree public partial class ItemInfoPanel : Tree
{ {
private Item _item; private ItemGroup _item;
#region Columns Definitions #region Columns Definitions
private const int EmptyColumn = 0; private const int EmptyColumn = 0;
@ -40,12 +41,12 @@ public partial class ItemInfoPanel : Tree
var value = node.GetText(ValueColumn); var value = node.GetText(ValueColumn);
if (prevKey != currentKey) if (prevKey != currentKey)
{ {
_item.Info.Remove(prevKey); _item.Remove(prevKey);
} }
_item.Info[currentKey] = value; _item.SetValue(currentKey, value);
} }
public void SetCurrentItem(Item item) public void SetCurrentItem(ItemGroup item)
{ {
_item = item; _item = item;
OnCurrentItemChanged(); OnCurrentItemChanged();
@ -57,14 +58,13 @@ public partial class ItemInfoPanel : Tree
_nodeKeys.Clear(); _nodeKeys.Clear();
if (_item == null) return; if (_item == null) return;
var root = CreateItem(); var root = CreateItem();
foreach (var kv in _item.Info) foreach (var key in _item.GetKeys())
{ {
var key = kv.Key; if(!_item.TryGetValue(key, out var value, out var isSame)) continue;
var value = kv.Value;
var node = CreateItem(root); var node = CreateItem(root);
node.SetText(KeyColumn, key); node.SetText(KeyColumn, key);
node.SetText(ValueColumn, value); node.SetText(ValueColumn, isSame ? value : "-");
node.SetEditable(KeyColumn, true); node.SetEditable(KeyColumn, true);
node.SetEditable(ValueColumn, true); node.SetEditable(ValueColumn, true);
_nodeKeys.Add(node, key); _nodeKeys.Add(node, key);
@ -76,12 +76,10 @@ public partial class ItemInfoPanel : Tree
if(_item == null) return; if(_item == null) return;
var newFieldName = "newField"; var newFieldName = "newField";
int index = 0; int index = 0;
while (_item.Info.ContainsKey(newFieldName + (index == 0 ? "" : index.ToString()))) while (!_item.TryAdd(newFieldName + (index == 0 ? "" : index.ToString()), ""))
{ {
index += 1; index += 1;
} }
newFieldName += (index == 0 ? "" : index.ToString());
_item.Info.Add(newFieldName, "");
OnCurrentItemChanged(); OnCurrentItemChanged();
} }
@ -93,7 +91,7 @@ public partial class ItemInfoPanel : Tree
var root = GetRoot(); var root = GetRoot();
while (node != null) while (node != null)
{ {
_item.Info.Remove(_nodeKeys[node]); _item.Remove(_nodeKeys[node]);
_nodeKeys.Remove(node); _nodeKeys.Remove(node);
var next = GetNextSelected(node); var next = GetNextSelected(node);
root.RemoveChild(node); root.RemoveChild(node);

View File

@ -1,5 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using Godot; using Godot;
using Learn.Models; using Learn.Models;
@ -10,19 +11,32 @@ public partial class LearnTree : Tree
[Export] [Export]
private ItemInfoPanel _itemInfoPanel; private ItemInfoPanel _itemInfoPanel;
private bool _updateItemInfoPanel;
private readonly HashSet<Item> _selectingItems = new ();
private readonly Dictionary<TreeItem, Item> _mapper = new();
public override void _Ready() public override void _Ready()
{ {
MultiSelected += OnMultiSelected; MultiSelected += OnMultiSelected;
} }
private void OnMultiSelected(TreeItem item, long column, bool selected) public override void _Process(double delta)
{ {
TreeItem first = GetSelected(); if (_updateItemInfoPanel)
if (first != null) _itemInfoPanel.SetCurrentItem(_mapper[first]); {
else _itemInfoPanel.SetCurrentItem(null); _updateItemInfoPanel = false;
_itemInfoPanel.SetCurrentItem(new ItemGroup(_selectingItems));
}
}
private void OnMultiSelected(TreeItem item, long column, bool selected)
{
if(selected) _selectingItems.Add(_mapper[item]);
else _selectingItems.Remove(_mapper[item]);
_updateItemInfoPanel = true;
} }
private readonly Dictionary<TreeItem, Item> _mapper = new();
private TreeItem CreateNode(TreeItem father, Item item) private TreeItem CreateNode(TreeItem father, Item item)
{ {
@ -71,8 +85,10 @@ public partial class LearnTree : Tree
if (string.IsNullOrEmpty(path)) return; if (string.IsNullOrEmpty(path)) return;
Clear(); Clear();
_mapper.Clear(); _mapper.Clear();
_selectingItems.Clear();
TreeItem root = CreateItem(); TreeItem root = CreateItem();
BuildTree(root, path); BuildTree(root, path);
_updateItemInfoPanel = true;
} }
} }

82
Models/ItemGroup.cs Normal file
View File

@ -0,0 +1,82 @@
using System.Collections.Generic;
using System.Linq;
namespace Learn.Models;
public class ItemGroup(IEnumerable<Item> items)
{
public IEnumerable<string> GetKeys()
{
IEnumerable<string> inter = null;
foreach (var item in items)
{
if (inter == null)
{
inter = item.Info.Keys;
}
else
{
inter = inter.Intersect(item.Info.Keys);
}
}
if(inter == null) return new List<string>();
return inter.ToList();
}
public bool TryGetValue(string key, out string value, out bool isSame)
{
value = null;
isSame = true;
if (!GetKeys().Contains(key)) return false;
bool isFirst = true;
foreach (var item in items)
{
if (isFirst)
{
isFirst = false;
}
else
{
isSame = value == item.Info[key];
if(!isSame) return true;
}
value = item.Info[key];
}
return true;
}
public void SetValue(string key, string value)
{
foreach (var item in items)
{
item.Info[key] = value;
}
}
public bool Remove(string key)
{
if (!GetKeys().Contains(key)) return false;
foreach (var item in items)
{
item.Info.Remove(key);
}
return true;
}
private bool AnyContains(string key)
{
return items.Any(item => item.Info.Keys.Contains(key));
}
public bool TryAdd(string key, string value)
{
if (AnyContains(key)) return false;
foreach (var item in items)
{
item.Info.Add(key, value);
}
return true;
}
}

1
Models/ItemGroup.cs.uid Normal file
View File

@ -0,0 +1 @@
uid://danmejsnufbuq