添加选择面板

This commit is contained in:
fengfeng 2025-12-15 14:06:17 +08:00
parent 2956b465c0
commit ce70970eda
5 changed files with 149 additions and 43 deletions

103
ItemInfoPanel.cs Normal file
View File

@ -0,0 +1,103 @@
using Godot;
using Godot.Collections;
using Learn.Models;
public partial class ItemInfoPanel : Tree
{
private Item _item;
#region Columns Definitions
private const int EmptyColumn = 0;
private const int KeyColumn = 1;
private const int ValueColumn = 2;
#endregion
public override void _Ready()
{
Columns = 3;
SetColumnTitlesVisible(true);
SetColumnCustomMinimumWidth(EmptyColumn, 30);
SetColumnExpand(EmptyColumn, false);
SetColumnTitle(KeyColumn, "键");
SetColumnCustomMinimumWidth(KeyColumn, 100);
SetColumnExpand(KeyColumn, false);
SetColumnTitle(ValueColumn, "值");
SetColumnExpand(ValueColumn, true);
ItemEdited += OnItemEdited;
}
private readonly Dictionary<TreeItem, string> _nodeKeys = new ();
private void OnItemEdited()
{
var node = GetEdited();
var prevKey = _nodeKeys[node];
var currentKey = node.GetText(KeyColumn);
var value = node.GetText(ValueColumn);
if (prevKey != currentKey)
{
_item.Info.Remove(prevKey);
}
_item.Info[currentKey] = value;
}
public void SetCurrentItem(Item item)
{
_item = item;
OnCurrentItemChanged();
}
private void OnCurrentItemChanged()
{
Clear();
_nodeKeys.Clear();
if (_item == null) return;
var root = CreateItem();
foreach (var kv in _item.Info)
{
var key = kv.Key;
var value = kv.Value;
var node = CreateItem(root);
node.SetText(KeyColumn, key);
node.SetText(ValueColumn, value);
node.SetEditable(KeyColumn, true);
node.SetEditable(ValueColumn, true);
_nodeKeys.Add(node, key);
}
}
private void AddKeyValue()
{
if(_item == null) return;
var newFieldName = "newField";
int index = 0;
while (_item.Info.ContainsKey(newFieldName + (index == 0 ? "" : index.ToString())))
{
index += 1;
}
newFieldName += (index == 0 ? "" : index.ToString());
_item.Info.Add(newFieldName, "");
OnCurrentItemChanged();
}
private void RemoveKeyValue()
{
if(_item == null) return;
var node = GetSelected();
var root = GetRoot();
while (node != null)
{
_item.Info.Remove(_nodeKeys[node]);
_nodeKeys.Remove(node);
var next = GetNextSelected(node);
root.RemoveChild(node);
node = next;
}
}
}

1
ItemInfoPanel.cs.uid Normal file
View File

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

View File

@ -0,0 +1,3 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATreeItem_002Ecs_002Fl_003AC_0021_003FUsers_003Flianzefeng_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F1c378f459c054fecaf4484a0fa6d44c055a800_003F1d_003Fbc7bd422_003FTreeItem_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATree_002Ecs_002Fl_003AC_0021_003FUsers_003Flianzefeng_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F1c378f459c054fecaf4484a0fa6d44c055a800_003F9d_003Fbcfb64ab_003FTree_002Ecs/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary>

View File

@ -7,50 +7,19 @@ public partial class LearnTree : Tree
{
[Export]
private FileDirSelector _dirSelector;
[Export]
private ItemInfoPanel _itemInfoPanel;
public override void _Ready()
{
ItemSelected += OnItemSelected;
MultiSelected += OnMultiSelected;
}
private void OnItemSelected()
private void OnMultiSelected(TreeItem item, long column, bool selected)
{
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");
TreeItem first = GetSelected();
if (first != null) _itemInfoPanel.SetCurrentItem(_mapper[first]);
else _itemInfoPanel.SetCurrentItem(null);
}
private readonly Dictionary<TreeItem, Item> _mapper = new();

View File

@ -1,6 +1,7 @@
[gd_scene load_steps=3 format=3 uid="uid://b3ypva4l8wfoh"]
[gd_scene load_steps=4 format=3 uid="uid://b3ypva4l8wfoh"]
[ext_resource type="Script" uid="uid://bngqk8kje5m2k" path="res://LearnTree.cs" id="1_brfkd"]
[ext_resource type="Script" uid="uid://dxkhiggkgqs6" path="res://ItemInfoPanel.cs" id="2_gvmkm"]
[ext_resource type="Script" uid="uid://hbu73fxqen34" path="res://FileDirSelector.cs" id="2_nnvrw"]
[node name="Control" type="Control"]
@ -27,17 +28,46 @@ layout_mode = 2
size_flags_vertical = 4
text = "打开文件夹"
[node name="Content" type="HBoxContainer" parent="VBoxContainer"]
[node name="HSplitContainer" type="HSplitContainer" parent="VBoxContainer"]
layout_mode = 2
size_flags_vertical = 3
[node name="Tree" type="Tree" parent="VBoxContainer/Content" node_paths=PackedStringArray("_dirSelector")]
[node name="Tree" type="Tree" parent="VBoxContainer/HSplitContainer" node_paths=PackedStringArray("_dirSelector", "_itemInfoPanel")]
custom_minimum_size = Vector2(700, 0)
layout_mode = 2
size_flags_horizontal = 3
allow_search = false
hide_root = true
select_mode = 2
script = ExtResource("1_brfkd")
_dirSelector = NodePath("../../../FileDirDialog")
_itemInfoPanel = NodePath("../VBoxContainer/ItemInfoPanel")
[node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/HSplitContainer"]
layout_mode = 2
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/HSplitContainer/VBoxContainer"]
layout_mode = 2
[node name="Add" type="Button" parent="VBoxContainer/HSplitContainer/VBoxContainer/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 0
text = "添加字段"
[node name="Remove" type="Button" parent="VBoxContainer/HSplitContainer/VBoxContainer/HBoxContainer"]
layout_mode = 2
text = "移除选中"
[node name="ItemInfoPanel" type="Tree" parent="VBoxContainer/HSplitContainer/VBoxContainer"]
layout_mode = 2
size_flags_vertical = 3
allow_search = false
hide_root = true
select_mode = 2
script = ExtResource("2_gvmkm")
[node name="FileDirDialog" type="FileDialog" parent="."]
script = ExtResource("2_nnvrw")
[connection signal="pressed" from="VBoxContainer/Toolbar/Button" to="VBoxContainer/Content/Tree" method="Open"]
[connection signal="pressed" from="VBoxContainer/Toolbar/Button" to="VBoxContainer/HSplitContainer/Tree" method="Open"]
[connection signal="pressed" from="VBoxContainer/HSplitContainer/VBoxContainer/HBoxContainer/Add" to="VBoxContainer/HSplitContainer/VBoxContainer/ItemInfoPanel" method="AddKeyValue"]
[connection signal="pressed" from="VBoxContainer/HSplitContainer/VBoxContainer/HBoxContainer/Remove" to="VBoxContainer/HSplitContainer/VBoxContainer/ItemInfoPanel" method="RemoveKeyValue"]