Files
Godot-test/scripts/inventory/InventoryTableManager.cs

335 lines
12 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}
}