GFramework/GFramework.Godot/ui/GodotUiRoot.cs
GeWuYou b49079de3e style(coding-style): 统一代码风格并优化文档格式
- 移除多余using语句和空行,统一代码缩进格式
- 优化注释文档中的缩进和对齐格式
- 简化条件语句和方法实现,提升代码可读性
- 重构协程系统相关类的字段和方法定义格式
- 更新架构服务中容器访问方式的实现
- 调整异步操作类的属性和方法组织结构
- [skip ci]
2026-01-27 20:30:04 +08:00

134 lines
4.2 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 GFramework.Game.Abstractions.enums;
using GFramework.Game.Abstractions.ui;
using Godot;
namespace GFramework.Godot.ui;
/// <summary>
/// Godot平台的UI根节点实现
/// 用于管理UI页面的添加、移除和层级排序
/// </summary>
public partial class GodotUiRoot(IReadOnlyDictionary<UiLayer, int>? layerZOrderMap) : Node, IUiRoot
{
/// <summary>
/// UI层级与Z轴顺序的映射表定义了不同UI层的渲染优先级
/// </summary>
/// <remarks>
/// 默认层级映射关系:
/// - Page: 0 (基础页面层)
/// - Overlay: 100 (覆盖层)
/// - Modal: 200 (模态窗口层)
/// - Toast: 300 (提示消息层)
/// - Topmost: 400 (最顶层)
/// </remarks>
private readonly IReadOnlyDictionary<UiLayer, int> _layerZOrderMap = layerZOrderMap ??
new Dictionary<UiLayer, int>
{
{ UiLayer.Page, 0 },
{ UiLayer.Overlay, 100 },
{ UiLayer.Modal, 200 },
{ UiLayer.Toast, 300 },
{ UiLayer.Topmost, 400 }
};
/// <summary>
/// UI页面的追踪字典记录每个页面的节点
/// </summary>
private readonly Dictionary<IUiPageBehavior, Node> _pageNodes = new();
/// <summary>
/// UI节点的父容器所有UI页面都添加到这个节点下
/// </summary>
private Node? _uiContainer;
/// <summary>
/// 向UI根节点添加子页面
/// </summary>
public void AddUiPage(IUiPageBehavior child)
{
if (_uiContainer == null)
throw new InvalidOperationException("UiContainer is not initialized");
var node = GetNodeFromPage(child);
if (node == null)
throw new InvalidOperationException($"Page node is null: {child.Key}");
if (!_pageNodes.TryAdd(child, node))
return;
if (node.GetParent() != _uiContainer) _uiContainer.AddChild(node);
}
/// <summary>
/// 向UI根节点添加子页面到指定层级
/// </summary>
public void AddUiPage(
IUiPageBehavior child,
UiLayer layer,
int orderInLayer = 0)
{
AddUiPage(child);
var z = GetBaseZOrder(layer) + orderInLayer;
SetZOrder(child, z);
}
/// <summary>
/// 从UI根节点移除子页面
/// </summary>
public void RemoveUiPage(IUiPageBehavior child)
{
if (!_pageNodes.Remove(child, out var node))
return;
if (_uiContainer != null && node.GetParent() == _uiContainer) _uiContainer.RemoveChild(node);
}
/// <summary>
/// 设置页面的Z-order层级顺序
/// </summary>
public void SetZOrder(IUiPageBehavior page, int zOrder)
{
if (!_pageNodes.TryGetValue(page, out var node))
return;
if (node is CanvasItem canvasItem) canvasItem.ZIndex = zOrder;
}
/// <summary>
/// 获取当前所有显示的页面
/// </summary>
public IReadOnlyList<IUiPageBehavior> GetVisiblePages()
{
return _pageNodes.Keys.ToList().AsReadOnly();
}
public override void _Ready()
{
// 创建UI容器节点
_uiContainer = new Node
{
Name = "UiContainer"
};
AddChild(_uiContainer);
}
/// <summary>
/// 从页面行为获取对应的节点
/// </summary>
private static Node? GetNodeFromPage(IUiPageBehavior page)
{
return page.View as Node;
}
private int GetBaseZOrder(UiLayer layer)
{
return !_layerZOrderMap.TryGetValue(layer, out var z)
? throw new ArgumentOutOfRangeException(nameof(layer), layer, null)
: z;
}
}