Files
Godot-test/scripts/ui/DynamicTabManager.cs

863 lines
31 KiB
C#
Raw 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;
using System.Linq;
public partial class DynamicTabManager : TabContainer
{
private PackedScene itemPanelScene;
private PackedScene craftingItemScene;
private PackedScene productionLineItemScene;
private PackedScene manualCollectionItemScene;
public override void _Ready()
{
GD.Print("DynamicTabManager _Ready 开始");
// 设置标签靠左对齐
TabAlignment = TabBar.AlignmentMode.Left;
// 加载ItemPanel场景用于生产线
itemPanelScene = GD.Load<PackedScene>("res://scenes/ItemPanel.tscn");
if (itemPanelScene == null)
{
GD.PrintErr("无法加载ItemPanel场景");
return;
}
// 加载CraftingItem场景用于合成
craftingItemScene = GD.Load<PackedScene>("res://scenes/CraftingItem.tscn");
if (craftingItemScene == null)
{
GD.PrintErr("无法加载CraftingItem场景");
return;
}
// 加载ProductionLineItem场景用于生产线
productionLineItemScene = GD.Load<PackedScene>("res://scenes/ProductionLineItem.tscn");
if (productionLineItemScene == null)
{
GD.PrintErr("无法加载ProductionLineItem场景");
return;
}
// 加载ManualCollectionItem场景用于手动采集
manualCollectionItemScene = GD.Load<PackedScene>("res://scenes/ManualCollectionItem.tscn");
if (manualCollectionItemScene == null)
{
GD.PrintErr("无法加载ManualCollectionItem场景");
return;
}
GD.Print("开始初始化标签页");
// 延迟初始化以确保所有管理器都已初始化
CallDeferred(nameof(InitializeTabs));
}
public void RefreshTabs()
{
GD.Print("刷新标签页");
InitializeTabs();
}
private void InitializeTabs()
{
GD.Print("开始创建固定标签页");
// 清空现有标签页
foreach (Node child in GetChildren())
{
child.QueueFree();
}
// 创建固定的标签页
CreateFixedTabs();
GD.Print("成功创建固定标签页");
}
private void CreateFixedTabs()
{
// 创建"合成"标签
CreateTabForCrafting();
// 创建"生产线"标签
CreateTabForProduction();
}
private void CreateTabForCrafting()
{
GD.Print("创建合成标签");
// 创建合成标签的滚动容器
var scrollContainer = new ScrollContainer();
scrollContainer.Name = "CraftingScroll";
// 创建垂直容器来放置所有分类块
var vboxContainer = new VBoxContainer();
vboxContainer.SizeFlagsHorizontal = Control.SizeFlags.ExpandFill;
vboxContainer.SizeFlagsVertical = Control.SizeFlags.ExpandFill;
scrollContainer.AddChild(vboxContainer);
// 获取所有分类
var categoryManager = ResourceCategoryManager.Instance;
if (categoryManager == null)
{
GD.PrintErr("ResourceCategoryManager 实例为null");
return;
}
var allCategories = categoryManager.GetAllCategories();
// 为合成相关的分类创建块
foreach (var category in allCategories)
{
// 合成标签包含:手动采集、冶炼、制作物品、建筑设施
if (category.CategoryName == "手动采集" ||
category.CategoryName == "冶炼" ||
category.CategoryName == "制作物品" ||
category.CategoryName == "建筑设施")
{
CreateCategoryBlock(vboxContainer, category, "合成");
}
}
// 添加到TabContainer
AddChild(scrollContainer);
SetTabTitle(GetTabCount() - 1, "合成");
}
private void CreateTabForProduction()
{
GD.Print("创建生产线标签");
// 创建生产线标签的滚动容器
var scrollContainer = new ScrollContainer();
scrollContainer.Name = "ProductionScroll";
// 创建垂直容器来放置所有分类块
var vboxContainer = new VBoxContainer();
vboxContainer.SizeFlagsHorizontal = Control.SizeFlags.ExpandFill;
vboxContainer.SizeFlagsVertical = Control.SizeFlags.ExpandFill;
scrollContainer.AddChild(vboxContainer);
// 获取生产线管理器
var productionLineManager = ProductionLineManager.Instance;
if (productionLineManager == null)
{
GD.PrintErr("ProductionLineManager 实例为null创建空的生产线标签");
// 创建一个提示标签
var noDataLabel = new Label();
noDataLabel.Text = "生产线管理器未初始化";
noDataLabel.HorizontalAlignment = HorizontalAlignment.Center;
noDataLabel.VerticalAlignment = VerticalAlignment.Center;
vboxContainer.AddChild(noDataLabel);
// 添加到TabContainer
AddChild(scrollContainer);
SetTabTitle(GetTabCount() - 1, "生产线");
return;
}
// 获取所有生产线分类
var categories = productionLineManager.GetAllCategories();
GD.Print($"获取到 {categories.Count} 个生产线分类");
if (categories.Count == 0)
{
GD.Print("没有找到生产线分类,创建提示标签");
// 创建一个提示标签
var noDataLabel = new Label();
noDataLabel.Text = "暂无生产线配置";
noDataLabel.HorizontalAlignment = HorizontalAlignment.Center;
noDataLabel.VerticalAlignment = VerticalAlignment.Center;
vboxContainer.AddChild(noDataLabel);
}
else
{
// 为每个分类创建块
foreach (var category in categories)
{
GD.Print($"处理生产线分类: {category}");
CreateProductionCategoryBlock(vboxContainer, category);
}
}
// 添加到TabContainer
AddChild(scrollContainer);
SetTabTitle(GetTabCount() - 1, "生产线");
GD.Print("生产线标签创建完成");
}
private void CreateProductionCategoryBlock(VBoxContainer parentContainer, string category)
{
GD.Print($"创建生产线分类块: {category}");
// 创建分类块的容器
var categoryContainer = new VBoxContainer();
categoryContainer.Name = $"{category}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;
titleLabel.HorizontalAlignment = HorizontalAlignment.Left;
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);
categoryContainer.AddChild(titleContainer);
// 创建流容器来放置生产线(完全按照合成菜单的方式)
var flowContainer = new FlowContainer();
flowContainer.SizeFlagsHorizontal = Control.SizeFlags.ExpandFill;
categoryContainer.AddChild(flowContainer);
// 添加该分类的所有生产线
AddProductionLinesToContainer(flowContainer, category);
// 添加到父容器
parentContainer.AddChild(categoryContainer);
}
private void AddProductionLinesToContainer(FlowContainer container, string category)
{
GD.Print($"为分类 '{category}' 添加生产线");
var productionLineManager = ProductionLineManager.Instance;
if (productionLineManager == null)
{
GD.PrintErr("ProductionLineManager 实例为null");
return;
}
// 获取该分类的所有生产线
var productionLines = productionLineManager.GetProductionLinesByCategory(category);
GD.Print($"获取到 {productionLines.Count} 条生产线");
foreach (var productionLine in productionLines)
{
// 创建ProductionLineItem实例
var productionLineItem = productionLineItemScene.Instantiate<ProductionLineItem>();
if (productionLineItem == null)
{
GD.PrintErr($"无法创建ProductionLineItem实例: {productionLine.Name}");
continue;
}
// 设置生产线数据
productionLineItem.SetupProductionLine(productionLine);
// 添加到容器
container.AddChild(productionLineItem);
GD.Print($"成功添加生产线: {productionLine.Name}");
}
}
private void CreateCategoryBlock(VBoxContainer parentContainer, ResourceCategoryManager.ResourceCategory category, string tabType)
{
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;
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);
categoryContainer.AddChild(titleContainer);
// 创建流容器来放置物品
var flowContainer = new FlowContainer();
flowContainer.SizeFlagsHorizontal = Control.SizeFlags.ExpandFill;
categoryContainer.AddChild(flowContainer);
// 获取分类中的物品数据
var items = ResourceCategoryManager.Instance?.GetItemsByCategory(category.CategoryName);
if (items == null)
{
GD.PrintErr($"无法获取分类 {category.CategoryName} 的物品数据");
return;
}
GD.Print($"分类 {category.CategoryName} 包含 {items.Count} 个物品");
// 为每个物品创建对应的面板
foreach (var itemPair in items)
{
string itemId = itemPair.Key;
var itemData = itemPair.Value;
string categoryName = category.CategoryName;
Control itemPanel;
// 手动采集使用新的ManualCollectionItem
if (categoryName == "手动采集")
{
// 使用专门的手动采集场景
itemPanel = manualCollectionItemScene.Instantiate<ManualCollectionItem>();
if (itemPanel == null)
{
GD.PrintErr($"无法实例化ManualCollectionItem for {itemId}");
continue;
}
// 设置手动采集物品数据
var manualCollectionItem = itemPanel as ManualCollectionItem;
manualCollectionItem?.SetupItem(itemId, itemData);
GD.Print($"为 {itemId} 创建手动采集面板");
}
// 其他合成物品根据标签类型选择面板
else if (tabType == "合成")
{
// 合成标签的非手动采集物品使用CraftingItem
itemPanel = craftingItemScene.Instantiate<Control>();
if (itemPanel == null)
{
GD.PrintErr($"无法实例化CraftingItem for {itemId}");
continue;
}
// 设置合成物品数据
SetupCraftingItem(itemPanel, itemData, categoryName);
}
else
{
// 生产线标签使用ItemPanel
itemPanel = itemPanelScene.Instantiate<Control>();
if (itemPanel == null)
{
GD.PrintErr($"无法实例化ItemPanel for {itemId}");
continue;
}
// 判断是否为生产设备
bool isProductionDevice = categoryName != "手动采集";
// 设置物品数据
SetupItemPanel(itemPanel, itemData, isProductionDevice);
}
// 添加到流容器
flowContainer.AddChild(itemPanel);
}
// 添加分类块到父容器
parentContainer.AddChild(categoryContainer);
GD.Print($"成功创建分类块: {category.CategoryName},包含 {items.Count} 个物品");
}
private void SetupItemPanel(Control itemPanel, GameData.ItemData itemData, bool isProductionDevice = true)
{
try
{
// 设置图标
var iconTexture = itemPanel.GetNode<TextureRect>("MarginContainer/VBoxContainer/TopRow/IconTexture");
if (iconTexture != null && !string.IsNullOrEmpty(itemData.IconPath))
{
// 检查文件是否存在
if (ResourceLoader.Exists(itemData.IconPath))
{
// 尝试加载为Texture2D资源
var resource = ResourceLoader.Load(itemData.IconPath);
if (resource is Texture2D texture)
{
iconTexture.Texture = texture;
GD.Print($"设置图标成功: {itemData.IconPath}");
}
else
{
GD.PrintErr($"资源不是Texture2D类型: {itemData.IconPath}");
LoadDefaultIcon(iconTexture);
}
}
else
{
GD.Print($"图标文件不存在: {itemData.IconPath},使用默认图标");
LoadDefaultIcon(iconTexture);
}
}
// 设置名称
var nameLabel = itemPanel.GetNode<Label>("MarginContainer/VBoxContainer/TopRow/MiddleContainer/TopInfoRow/NameLabel");
if (nameLabel != null)
{
nameLabel.Text = itemData.Name;
GD.Print($"设置名称成功: {itemData.Name}");
}
// 设置产率
var productionLabel = itemPanel.GetNode<Label>("MarginContainer/VBoxContainer/TopRow/MiddleContainer/TopInfoRow/ProductionLabel");
if (productionLabel != null)
{
if (isProductionDevice)
{
productionLabel.Text = "0/s"; // 生产设备显示产率
}
else
{
productionLabel.Text = "手动"; // 手动采集显示"手动"
productionLabel.Modulate = new Color(0.8f, 1.0f, 0.8f, 1.0f); // 淡绿色
}
}
// 根据isProductionDevice决定是否显示设备相关UI
var rightContainer = itemPanel.GetNode<VBoxContainer>("MarginContainer/VBoxContainer/TopRow/RightContainer");
if (rightContainer != null)
{
rightContainer.Visible = isProductionDevice;
}
if (isProductionDevice)
{
// 设置设备数量
var deviceLabel = itemPanel.GetNode<Label>("MarginContainer/VBoxContainer/TopRow/RightContainer/BottomDeviceRow/DeviceLabel");
if (deviceLabel != null)
{
deviceLabel.Text = "设备: 0"; // 默认设备数量
}
// 设置功耗
var powerLabel = itemPanel.GetNode<Label>("MarginContainer/VBoxContainer/TopRow/RightContainer/PowerLabel");
if (powerLabel != null)
{
powerLabel.Text = "-0W"; // 默认功耗
}
}
// 设置进度条
var progressFill = itemPanel.GetNode<ColorRect>("MarginContainer/VBoxContainer/ProgressContainer/ProgressFill");
if (progressFill != null)
{
if (isProductionDevice)
{
progressFill.AnchorRight = 0.0f; // 生产设备默认0%进度
}
else
{
// 手动采集默认0%进度,采集时会动态变化
progressFill.AnchorRight = 0.0f; // 0% 进度
progressFill.Color = new Color(0.3f, 0.8f, 0.3f, 1.0f); // 绿色
}
}
}
catch (System.Exception e)
{
GD.PrintErr($"设置ItemPanel时出错: {e.Message}");
}
}
private void SetupCraftingItem(Control craftingItem, GameData.ItemData itemData, string categoryName)
{
try
{
// 设置图标
var iconTexture = craftingItem.GetNode<TextureRect>("MarginContainer/HBoxContainer/IconTexture");
if (iconTexture != null && !string.IsNullOrEmpty(itemData.IconPath))
{
// 检查文件是否存在
if (ResourceLoader.Exists(itemData.IconPath))
{
// 尝试加载为Texture2D资源
var resource = ResourceLoader.Load(itemData.IconPath);
if (resource is Texture2D texture)
{
iconTexture.Texture = texture;
GD.Print($"设置合成物品图标成功: {itemData.IconPath}");
}
else
{
GD.PrintErr($"资源不是Texture2D类型: {itemData.IconPath}");
LoadDefaultIcon(iconTexture);
}
}
else
{
GD.Print($"合成物品图标文件不存在: {itemData.IconPath},使用默认图标");
LoadDefaultIcon(iconTexture);
}
}
// 设置名称
var nameLabel = craftingItem.GetNode<Label>("MarginContainer/HBoxContainer/MiddleContainer/NameLabel");
if (nameLabel != null)
{
nameLabel.Text = itemData.Name;
GD.Print($"设置合成物品名称成功: {itemData.Name}");
}
// 从合成配方系统获取真实信息
var recipes = CraftingRecipeManager.Instance?.GetRecipesForItem(itemData.Id);
var recipe = recipes?.Count > 0 ? recipes[0] : null;
// 设置材料需求(现在在物品名称下面)
var materialsLabel = craftingItem.GetNode<Label>("MarginContainer/HBoxContainer/MiddleContainer/MaterialsLabel");
if (materialsLabel != null)
{
if (recipe != null && recipe.Ingredients.Count > 0)
{
// 显示第一个材料,如果有多个材料可以显示"..."
var firstIngredient = recipe.Ingredients[0];
if (recipe.Ingredients.Count <= 3)
{
materialsLabel.Text = $"材料:{string.Join(" ", recipe.Ingredients.Select(s => $"{s.Quantity}x{ GameData.Instance?.GetItem(s.ItemId)?.Name ?? s.ItemId}"))}";
}
else
{
var itemName = GameData.Instance?.GetItem(firstIngredient.ItemId)?.Name ?? firstIngredient.ItemId;
materialsLabel.Text = $"材料: {firstIngredient.Quantity}x{itemName}...";
}
}
else
{
materialsLabel.Text = "无需材料";
}
}
// 设置合成时间(现在在材料下面)
var craftTimeLabel = craftingItem.GetNode<Label>("MarginContainer/HBoxContainer/MiddleContainer/InfoRow/CraftTimeLabel");
if (craftTimeLabel != null)
{
if (recipe != null)
{
craftTimeLabel.Text = $"{recipe.CraftingTime:F1}s";
}
else
{
craftTimeLabel.Text = "无配方";
craftTimeLabel.Modulate = new Color(1.0f, 0.5f, 0.5f, 1.0f); // 红色表示无配方
}
}
// 设置合成方式(现在在材料下面)
var methodLabel = craftingItem.GetNode<Label>("MarginContainer/HBoxContainer/MiddleContainer/InfoRow/MethodLabel");
if (methodLabel != null)
{
if (recipe != null)
{
methodLabel.Text = recipe.CraftingMethod;
}
else if (categoryName == "手动采集")
{
methodLabel.Text = "手动";
}
else if (categoryName == "冶炼")
{
methodLabel.Text = "冶炼";
}
else
{
methodLabel.Text = "制作";
}
}
// 设置合成按钮
var craftButton = craftingItem.GetNode<Button>("MarginContainer/HBoxContainer/RightContainer/CraftButton");
if (craftButton != null)
{
// 如果没有配方,禁用按钮
if (recipe == null)
{
craftButton.Disabled = true;
craftButton.Text = "无配方";
craftButton.Modulate = new Color(0.6f, 0.6f, 0.6f, 1.0f);
}
else
{
craftButton.Disabled = false;
craftButton.Text = "合成";
craftButton.Modulate = new Color(1.0f, 1.0f, 1.0f, 1.0f);
// 连接按钮点击事件
craftButton.Pressed += () => OnCraftButtonPressed(itemData.Id, craftingItem);
}
}
// 设置数量控制组件
SetupQuantityControls(craftingItem, recipe != null);
}
catch (System.Exception e)
{
GD.PrintErr($"设置CraftingItem时出错: {e.Message}");
}
}
private void LoadDefaultIcon(TextureRect iconTexture)
{
var defaultIcon = GD.Load<Texture2D>("res://assets/textures/icon.svg");
if (defaultIcon != null)
{
iconTexture.Texture = defaultIcon;
}
else
{
GD.PrintErr("无法加载默认图标");
}
}
private void LoadDefaultIconForCrafting(TextureRect iconTexture)
{
var defaultIcon = GD.Load<Texture2D>("res://assets/textures/icon.svg");
if (defaultIcon != null)
{
iconTexture.Texture = defaultIcon;
}
else
{
GD.PrintErr("无法加载默认图标");
}
}
private void OnCraftButtonPressed(string itemId, Control craftingItem)
{
GD.Print($"点击合成按钮: {itemId}");
// 检查合成配方管理器是否可用
if (CraftingRecipeManager.Instance == null)
{
GD.PrintErr("CraftingRecipeManager 实例为null无法进行合成");
return;
}
// 查询该物品的合成配方
var recipes = CraftingRecipeManager.Instance.GetRecipesForItem(itemId);
if (recipes == null || recipes.Count == 0)
{
GD.Print($"物品 {itemId} 没有找到合成配方");
return;
}
// 使用第一个找到的配方(后续可以扩展为让用户选择)
var recipe = recipes[0];
GD.Print($"找到合成配方: {recipe.Id} - {recipe.OutputItem}");
// 获取数量输入框的值
int quantity = 1;
try
{
var quantityInput = craftingItem.GetNode<LineEdit>("MarginContainer/HBoxContainer/RightContainer/QuantityContainer/QuantityInput");
if (quantityInput != null)
{
quantity = GetQuantityValue(quantityInput);
}
}
catch (System.Exception e)
{
GD.PrintErr($"获取数量输入值时出错: {e.Message}");
quantity = 1; // 默认为1
}
GD.Print($"准备合成 {quantity} 个 {itemId}");
// 检查是否有足够的材料制作指定数量
bool canCraftAll = true;
var insufficientMaterials = new List<string>();
foreach (var ingredient in recipe.Ingredients)
{
int currentAmount = InventoryManager.Instance?.GetItemQuantity(ingredient.ItemId) ?? 0;
int requiredAmount = ingredient.Quantity * quantity;
if (currentAmount < requiredAmount)
{
canCraftAll = false;
var itemName = GameData.Instance?.GetItem(ingredient.ItemId)?.Name ?? ingredient.ItemId;
insufficientMaterials.Add($"{itemName} (需要 {requiredAmount}, 当前 {currentAmount})");
}
}
if (!canCraftAll)
{
GD.Print($"材料不足,无法合成 {quantity} 个 {itemId}");
foreach (var material in insufficientMaterials)
{
GD.Print($"缺少材料: {material}");
}
return;
}
// 获取合成队列管理器
var craftingQueue = GetCraftingQueueManager();
if (craftingQueue == null)
{
GD.PrintErr("无法找到CraftingQueueManager无法添加到合成队列");
return;
}
// 批量添加到合成队列(一次性添加指定数量)
bool success = craftingQueue.AddToQueue(recipe.Id, quantity);
if (success)
{
GD.Print($"成功添加 {quantity} 个 {itemId} 到合成队列");
}
else
{
GD.Print($"添加 {itemId} 到合成队列失败(可能队列已满)");
}
}
private CraftingQueueManager GetCraftingQueueManager()
{
// 从场景树中查找CraftingQueueManager
// 它应该在GameScene下的左侧面板中
var gameScene = GetTree().CurrentScene;
if (gameScene == null)
{
GD.PrintErr("无法获取当前场景");
return null;
}
// 尝试通过路径查找CraftingQueueManager
var craftingQueue = gameScene.GetNode<CraftingQueueManager>("HBoxContainer/LeftPanel/VBoxContainer/CraftingQueue");
if (craftingQueue == null)
{
GD.PrintErr("无法找到CraftingQueueManager节点");
}
return craftingQueue;
}
private void SetupQuantityControls(Control craftingItem, bool hasRecipe)
{
try
{
var quantityInput = craftingItem.GetNode<LineEdit>("MarginContainer/HBoxContainer/RightContainer/QuantityContainer/QuantityInput");
var minusButton = craftingItem.GetNode<Button>("MarginContainer/HBoxContainer/RightContainer/QuantityContainer/MinusButton");
var plusButton = craftingItem.GetNode<Button>("MarginContainer/HBoxContainer/RightContainer/QuantityContainer/PlusButton");
if (quantityInput != null && minusButton != null && plusButton != null)
{
// 设置初始值
quantityInput.Text = "1";
// 如果没有配方,禁用数量控制
quantityInput.Editable = hasRecipe;
minusButton.Disabled = !hasRecipe;
plusButton.Disabled = !hasRecipe;
if (!hasRecipe)
{
quantityInput.Modulate = new Color(0.6f, 0.6f, 0.6f, 1.0f);
minusButton.Modulate = new Color(0.6f, 0.6f, 0.6f, 1.0f);
plusButton.Modulate = new Color(0.6f, 0.6f, 0.6f, 1.0f);
}
// 连接减号按钮事件
minusButton.Pressed += () =>
{
int currentValue = GetQuantityValue(quantityInput);
if (currentValue > 1)
{
quantityInput.Text = (currentValue - 1).ToString();
}
};
// 连接加号按钮事件
plusButton.Pressed += () =>
{
int currentValue = GetQuantityValue(quantityInput);
if (currentValue < 99) // 限制最大值为99
{
quantityInput.Text = (currentValue + 1).ToString();
}
};
// 连接输入框文本变化事件
quantityInput.TextChanged += (string newText) =>
{
ValidateQuantityInput(quantityInput, newText);
};
}
}
catch (System.Exception e)
{
GD.PrintErr($"设置数量控制组件时出错: {e.Message}");
}
}
private int GetQuantityValue(LineEdit quantityInput)
{
if (int.TryParse(quantityInput.Text, out int value))
{
return Mathf.Clamp(value, 1, 99);
}
return 1;
}
private void ValidateQuantityInput(LineEdit quantityInput, string newText)
{
// 只允许数字输入
if (string.IsNullOrEmpty(newText))
{
quantityInput.Text = "1";
return;
}
if (int.TryParse(newText, out int value))
{
// 限制范围在1-99之间
value = Mathf.Clamp(value, 1, 99);
if (value.ToString() != newText)
{
quantityInput.Text = value.ToString();
quantityInput.CaretColumn = quantityInput.Text.Length;
}
}
else
{
// 如果不是有效数字恢复为1
quantityInput.Text = "1";
quantityInput.CaretColumn = quantityInput.Text.Length;
}
}
}