335 lines
12 KiB
C#
335 lines
12 KiB
C#
using Godot;
|
||
using System.Collections.Generic;
|
||
|
||
public partial class InventoryTableManager : VBoxContainer
|
||
{
|
||
private PackedScene inventoryItemScene;
|
||
private Dictionary<string, GridContainer> categoryContainers = new Dictionary<string, GridContainer>();
|
||
|
||
public override void _Ready()
|
||
{
|
||
GD.Print("InventoryTableManager _Ready 开始");
|
||
|
||
// 设置父级ScrollContainer的滚动条宽度
|
||
var scrollContainer = GetParent() as ScrollContainer;
|
||
if (scrollContainer != null)
|
||
{
|
||
// 直接在滚动条组件上设置主题覆盖
|
||
var vScrollBar = scrollContainer.GetVScrollBar();
|
||
var hScrollBar = scrollContainer.GetHScrollBar();
|
||
|
||
if (vScrollBar != null)
|
||
{
|
||
// 尝试多种不同的属性名称
|
||
vScrollBar.AddThemeConstantOverride("width", 1);
|
||
vScrollBar.AddThemeConstantOverride("scroll_bar_width", 1);
|
||
vScrollBar.AddThemeConstantOverride("scrollbar_width", 1);
|
||
vScrollBar.AddThemeConstantOverride("bar_width", 1);
|
||
|
||
// 创建超细的样式框
|
||
var thinStyle = new StyleBoxFlat();
|
||
thinStyle.BgColor = new Color(0.3f, 0.3f, 0.3f, 0.6f);
|
||
thinStyle.SetContentMarginAll(0);
|
||
|
||
var thinGrabber = new StyleBoxFlat();
|
||
thinGrabber.BgColor = new Color(0.7f, 0.7f, 0.7f, 0.8f);
|
||
thinGrabber.SetContentMarginAll(0);
|
||
|
||
// 应用样式
|
||
vScrollBar.AddThemeStyleboxOverride("scroll", thinStyle);
|
||
vScrollBar.AddThemeStyleboxOverride("grabber", thinGrabber);
|
||
vScrollBar.AddThemeStyleboxOverride("grabber_highlight", thinGrabber);
|
||
vScrollBar.AddThemeStyleboxOverride("grabber_pressed", thinGrabber);
|
||
|
||
// 设置最小尺寸
|
||
vScrollBar.CustomMinimumSize = new Vector2(1, 0);
|
||
|
||
GD.Print("设置垂直滚动条样式和宽度");
|
||
}
|
||
|
||
|
||
GD.Print("已直接在滚动条组件上应用超细样式");
|
||
}
|
||
|
||
// 加载库存物品场景
|
||
inventoryItemScene = GD.Load<PackedScene>("res://scenes/InventoryItem.tscn");
|
||
if (inventoryItemScene == null)
|
||
{
|
||
GD.PrintErr("无法加载InventoryItem场景");
|
||
return;
|
||
}
|
||
|
||
// 初始化库存显示
|
||
InitializeInventoryDisplay();
|
||
|
||
// 订阅库存变化事件
|
||
if (InventoryManager.Instance != null)
|
||
{
|
||
InventoryManager.Instance.InventoryChanged += OnInventoryChanged;
|
||
}
|
||
|
||
GD.Print("InventoryTableManager 初始化完成");
|
||
}
|
||
|
||
private void InitializeInventoryDisplay()
|
||
{
|
||
GD.Print("初始化库存Table显示");
|
||
|
||
// 等待InventoryCategoryManager初始化
|
||
if (InventoryCategoryManager.Instance == null)
|
||
{
|
||
CallDeferred(nameof(InitializeInventoryDisplay));
|
||
return;
|
||
}
|
||
|
||
CreateCategoryBlocks();
|
||
UpdateInventoryDisplay();
|
||
}
|
||
|
||
private void CreateCategoryBlocks()
|
||
{
|
||
// 清空现有内容
|
||
foreach (Node child in GetChildren())
|
||
{
|
||
child.QueueFree();
|
||
}
|
||
categoryContainers.Clear();
|
||
|
||
var categories = InventoryCategoryManager.Instance.GetAllCategories();
|
||
|
||
foreach (var category in categories)
|
||
{
|
||
CreateCategoryBlock(category);
|
||
}
|
||
}
|
||
|
||
private void CreateCategoryBlock(InventoryCategoryManager.InventoryCategory category)
|
||
{
|
||
GD.Print($"创建库存分类块: {category.CategoryName}");
|
||
|
||
// 创建分类容器
|
||
var categoryContainer = new VBoxContainer();
|
||
categoryContainer.Name = $"{category.CategoryName}Block";
|
||
|
||
// 添加顶部间距
|
||
var topSpacer = new Control();
|
||
topSpacer.CustomMinimumSize = new Vector2(0, 10);
|
||
categoryContainer.AddChild(topSpacer);
|
||
|
||
// 创建标题行
|
||
var titleContainer = new HBoxContainer();
|
||
|
||
// 分类名称标签
|
||
var titleLabel = new Label();
|
||
titleLabel.Text = category.CategoryName;
|
||
titleLabel.HorizontalAlignment = HorizontalAlignment.Left;
|
||
titleLabel.AddThemeFontSizeOverride("font_size", 14);
|
||
titleLabel.Modulate = new Color(0.9f, 0.9f, 0.9f, 1.0f);
|
||
titleContainer.AddChild(titleLabel);
|
||
|
||
// 添加小间距
|
||
var labelSpacer = new Control();
|
||
labelSpacer.CustomMinimumSize = new Vector2(10, 0);
|
||
titleContainer.AddChild(labelSpacer);
|
||
|
||
// HSeparator 横线分隔符
|
||
var separator = new HSeparator();
|
||
separator.SizeFlagsHorizontal = Control.SizeFlags.ExpandFill;
|
||
separator.SizeFlagsVertical = Control.SizeFlags.ShrinkCenter;
|
||
titleContainer.AddChild(separator);
|
||
|
||
// 添加右侧间距,避免内容紧贴滚动条
|
||
var rightSpacer = new Control();
|
||
rightSpacer.CustomMinimumSize = new Vector2(10, 0);
|
||
titleContainer.AddChild(rightSpacer);
|
||
|
||
categoryContainer.AddChild(titleContainer);
|
||
|
||
// 添加小间距
|
||
var spacer = new Control();
|
||
spacer.CustomMinimumSize = new Vector2(0, 5);
|
||
categoryContainer.AddChild(spacer);
|
||
|
||
// 创建物品列表容器 - 使用GridContainer实现每行2个物品
|
||
var itemsContainer = new GridContainer();
|
||
itemsContainer.Name = $"{category.CategoryName}Items";
|
||
itemsContainer.Columns = 2; // 每行2列
|
||
itemsContainer.SizeFlagsHorizontal = Control.SizeFlags.ExpandFill;
|
||
itemsContainer.AddThemeConstantOverride("h_separation", 4); // 减少水平间距
|
||
itemsContainer.AddThemeConstantOverride("v_separation", 4); // 垂直间距
|
||
|
||
// 创建一个HBoxContainer来包装GridContainer,以便添加右侧间距
|
||
var itemsWrapper = new HBoxContainer();
|
||
itemsWrapper.AddChild(itemsContainer);
|
||
|
||
// 添加右侧间距
|
||
var itemsRightSpacer = new Control();
|
||
itemsRightSpacer.CustomMinimumSize = new Vector2(10, 0);
|
||
itemsWrapper.AddChild(itemsRightSpacer);
|
||
|
||
categoryContainer.AddChild(itemsWrapper);
|
||
|
||
// 保存容器引用
|
||
categoryContainers[category.CategoryName] = itemsContainer;
|
||
|
||
// 添加到主容器
|
||
AddChild(categoryContainer);
|
||
}
|
||
|
||
private void OnInventoryChanged(string itemId, int oldQuantity, int newQuantity)
|
||
{
|
||
GD.Print($"库存Table变化: {itemId} {oldQuantity} -> {newQuantity}");
|
||
UpdateInventoryDisplay();
|
||
}
|
||
|
||
private void UpdateInventoryDisplay()
|
||
{
|
||
if (InventoryManager.Instance == null || InventoryCategoryManager.Instance == null)
|
||
{
|
||
return;
|
||
}
|
||
|
||
// 清空所有分类的物品显示
|
||
foreach (var container in categoryContainers.Values)
|
||
{
|
||
foreach (Node child in container.GetChildren())
|
||
{
|
||
child.QueueFree();
|
||
}
|
||
}
|
||
|
||
// 获取所有分类并更新显示
|
||
var categories = InventoryCategoryManager.Instance.GetAllCategories();
|
||
|
||
foreach (var category in categories)
|
||
{
|
||
UpdateCategoryDisplay(category);
|
||
}
|
||
}
|
||
|
||
private void UpdateCategoryDisplay(InventoryCategoryManager.InventoryCategory category)
|
||
{
|
||
if (!categoryContainers.ContainsKey(category.CategoryName))
|
||
{
|
||
return;
|
||
}
|
||
|
||
var container = categoryContainers[category.CategoryName];
|
||
var items = InventoryCategoryManager.Instance.GetItemsByCategory(category.CategoryName);
|
||
|
||
foreach (var kvp in items)
|
||
{
|
||
var itemId = kvp.Key;
|
||
var itemData = kvp.Value;
|
||
|
||
// 获取库存数量
|
||
int quantity = InventoryManager.Instance.GetItemQuantity(itemId);
|
||
|
||
// 只显示有库存的物品,或者显示所有物品(包括0数量)
|
||
// 这里我们选择显示所有物品,0数量的显示为灰色
|
||
CreateInventoryItemDisplay(container, itemData, quantity);
|
||
}
|
||
}
|
||
|
||
private void CreateInventoryItemDisplay(GridContainer container, GameData.ItemData itemData, int quantity)
|
||
{
|
||
// 实例化库存物品UI
|
||
var inventoryItem = inventoryItemScene.Instantiate<Control>();
|
||
if (inventoryItem == null)
|
||
{
|
||
GD.PrintErr($"无法实例化InventoryItem for {itemData.Name}");
|
||
return;
|
||
}
|
||
|
||
// 设置尺寸标志,让物品能够填充分配的空间
|
||
inventoryItem.SizeFlagsHorizontal = Control.SizeFlags.ExpandFill;
|
||
inventoryItem.SizeFlagsVertical = Control.SizeFlags.ShrinkCenter;
|
||
|
||
// 设置图标
|
||
var iconTexture = inventoryItem.GetNode<TextureRect>("MarginContainer/HBoxContainer/IconTexture");
|
||
if (iconTexture != null && !string.IsNullOrEmpty(itemData.IconPath))
|
||
{
|
||
GD.Print($"图标路径: {itemData.IconPath}");
|
||
// 检查文件是否存在
|
||
if (ResourceLoader.Exists(itemData.IconPath))
|
||
{
|
||
// 尝试加载为Texture2D资源
|
||
var resource = ResourceLoader.Load(itemData.IconPath);
|
||
if (resource is Texture2D textureResource)
|
||
{
|
||
|
||
iconTexture.Texture = textureResource;
|
||
}
|
||
else
|
||
{
|
||
GD.PrintErr($"资源不是Texture2D类型: {itemData.IconPath}");
|
||
// 使用默认图标
|
||
var defaultIcon = GD.Load<Texture2D>("res://assets/textures/icon.svg");
|
||
if (defaultIcon != null)
|
||
{
|
||
iconTexture.Texture = defaultIcon;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// GD.Print($"图标文件不存在: {itemData.IconPath},使用默认图标");
|
||
// // 使用默认图标
|
||
// var defaultIcon = GD.Load<Texture2D>("res://assets/textures/icon.svg");
|
||
// if (defaultIcon != null)
|
||
// {
|
||
// iconTexture.Texture = defaultIcon;
|
||
// }
|
||
}
|
||
}
|
||
|
||
// 设置名称
|
||
var nameLabel = inventoryItem.GetNode<Label>("MarginContainer/HBoxContainer/NameLabel");
|
||
if (nameLabel != null)
|
||
{
|
||
nameLabel.Text = itemData.Name;
|
||
|
||
// 如果数量为0,设置为灰色
|
||
if (quantity == 0)
|
||
{
|
||
nameLabel.Modulate = new Color(0.6f, 0.6f, 0.6f, 1.0f);
|
||
}
|
||
else
|
||
{
|
||
nameLabel.Modulate = new Color(1.0f, 1.0f, 1.0f, 1.0f);
|
||
}
|
||
}
|
||
|
||
// 设置数量
|
||
var quantityLabel = inventoryItem.GetNode<Label>("MarginContainer/HBoxContainer/QuantityLabel");
|
||
if (quantityLabel != null)
|
||
{
|
||
quantityLabel.Text = quantity.ToString();
|
||
|
||
// 根据数量设置颜色
|
||
if (quantity == 0)
|
||
{
|
||
quantityLabel.Modulate = new Color(0.6f, 0.6f, 0.6f, 1.0f);
|
||
}
|
||
else if (quantity < 10)
|
||
{
|
||
quantityLabel.Modulate = new Color(1.0f, 0.8f, 0.4f, 1.0f); // 橙色 - 库存较低
|
||
}
|
||
else
|
||
{
|
||
quantityLabel.Modulate = new Color(0.8f, 1.0f, 0.8f, 1.0f); // 绿色 - 库存充足
|
||
}
|
||
}
|
||
|
||
container.AddChild(inventoryItem);
|
||
}
|
||
|
||
public override void _ExitTree()
|
||
{
|
||
// 取消订阅事件
|
||
if (InventoryManager.Instance != null)
|
||
{
|
||
InventoryManager.Instance.InventoryChanged -= OnInventoryChanged;
|
||
}
|
||
}
|
||
} |