mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-22 10:34:30 +08:00
refactor(ui): 移除UI根接口中的Z序管理方法并优化文档注释
- 从IUiRoot接口中移除SetZOrder和GetVisiblePages方法 - 删除GodotUiRoot类的完整实现文件 - 为ModalLayerUiPageBehavior类添加详细的XML文档注释 - 为TopmostLayerUiPageBehavior类添加详细的XML文档注释 - 优化模态层和顶层UI行为类的属性文档说明 - [release ci]
This commit is contained in:
parent
35a06d2565
commit
43eacc1e4a
@ -26,17 +26,4 @@ public interface IUiRoot
|
||||
/// </summary>
|
||||
/// <param name="child">要移除的UI页面子节点</param>
|
||||
void RemoveUiPage(IUiPageBehavior child);
|
||||
|
||||
/// <summary>
|
||||
/// 设置页面的Z-order(层级顺序)
|
||||
/// </summary>
|
||||
/// <param name="page">UI页面</param>
|
||||
/// <param name="zOrder">Z-order值</param>
|
||||
void SetZOrder(IUiPageBehavior page, int zOrder);
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前所有显示的页面
|
||||
/// </summary>
|
||||
/// <returns>所有显示的页面列表</returns>
|
||||
IReadOnlyList<IUiPageBehavior> GetVisiblePages();
|
||||
}
|
||||
@ -1,134 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -17,30 +17,35 @@ using Godot;
|
||||
namespace GFramework.Godot.ui;
|
||||
|
||||
/// <summary>
|
||||
/// 模态层 UI 行为 - 可重入但需谨慎,带遮罩阻止下层交互
|
||||
/// 模态层 UI 行为类,用于管理模态界面的行为。
|
||||
/// 此类继承自 CanvasItemUiPageBehaviorBase,提供模态层特有的功能:
|
||||
/// - 支持可重入(IsReentrant = true)
|
||||
/// - 带有遮罩以阻止下层交互(BlocksInput = true)
|
||||
/// - 属于模态层级(Layer = UiLayer.Modal)
|
||||
/// </summary>
|
||||
/// <typeparam name="T">拥有者类型,必须是 CanvasItem 的子类</typeparam>
|
||||
/// <param name="owner">当前行为的拥有者对象</param>
|
||||
/// <param name="key">用于标识此行为的键值</param>
|
||||
public class ModalLayerUiPageBehavior<T>(T owner, string key) : CanvasItemUiPageBehaviorBase<T>(owner, key)
|
||||
where T : CanvasItem
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取当前 UI 所属的层级,此处固定为模态层。
|
||||
/// </summary>
|
||||
public override UiLayer Layer => UiLayer.Modal;
|
||||
public override bool IsReentrant => true; // ✅ 支持重入(如多层确认弹窗)
|
||||
public override bool IsModal => true; // 模态窗口
|
||||
public override bool BlocksInput => true; // 必须阻止下层交互
|
||||
|
||||
/// <summary>
|
||||
/// 模态窗口显示时,可以添加遮罩逻辑
|
||||
/// 指示当前 UI 是否支持可重入。设置为 true 表示允许重复进入同一界面。
|
||||
/// </summary>
|
||||
public override void OnShow()
|
||||
{
|
||||
base.OnShow();
|
||||
// TODO: 可在此添加半透明遮罩层
|
||||
// AddModalMask();
|
||||
}
|
||||
public override bool IsReentrant => true;
|
||||
|
||||
public override void OnHide()
|
||||
{
|
||||
// TODO: 移除遮罩层
|
||||
// RemoveModalMask();
|
||||
base.OnHide();
|
||||
}
|
||||
/// <summary>
|
||||
/// 指示当前 UI 是否为模态界面。设置为 true 表示该界面会阻止用户与下层界面交互。
|
||||
/// </summary>
|
||||
public override bool IsModal => true;
|
||||
|
||||
/// <summary>
|
||||
/// 指示当前 UI 是否阻止输入事件传递到下层界面。设置为 true 表示启用遮罩功能。
|
||||
/// </summary>
|
||||
public override bool BlocksInput => true;
|
||||
}
|
||||
@ -17,30 +17,36 @@ using Godot;
|
||||
namespace GFramework.Godot.ui;
|
||||
|
||||
/// <summary>
|
||||
/// 顶层 UI 行为 - 不可重入,最高优先级,用于系统级弹窗
|
||||
/// 顶层 UI 行为类,继承自 CanvasItemUiPageBehaviorBase。
|
||||
/// 此类用于实现系统级弹窗行为,具有不可重入、最高优先级和模态特性。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">泛型参数,表示拥有此行为的 CanvasItem 类型。</typeparam>
|
||||
/// <param name="owner">拥有此行为的 CanvasItem 实例。</param>
|
||||
/// <param name="key">用于标识此行为的唯一键。</param>
|
||||
public class TopmostLayerUiPageBehavior<T>(T owner, string key) : CanvasItemUiPageBehaviorBase<T>(owner, key)
|
||||
where T : CanvasItem
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取当前 UI 行为所在的层级。
|
||||
/// 返回值为 UiLayer.Topmost,表示该行为位于最顶层。
|
||||
/// </summary>
|
||||
public override UiLayer Layer => UiLayer.Topmost;
|
||||
public override bool IsReentrant => false; // ❌ 顶层不支持重入
|
||||
public override bool IsModal => true; // 顶层通常是模态的
|
||||
public override bool BlocksInput => true; // 必须阻止所有下层交互
|
||||
|
||||
/// <summary>
|
||||
/// 顶层显示时,可以禁用所有下层 UI
|
||||
/// 指示此行为是否可重入。
|
||||
/// 返回值为 false,表示不可重入。
|
||||
/// </summary>
|
||||
public override void OnShow()
|
||||
{
|
||||
base.OnShow();
|
||||
// TODO: 可在此禁用其他所有层级
|
||||
// DisableAllLowerLayers();
|
||||
}
|
||||
public override bool IsReentrant => false;
|
||||
|
||||
public override void OnHide()
|
||||
{
|
||||
// TODO: 恢复其他层级
|
||||
// EnableAllLowerLayers();
|
||||
base.OnHide();
|
||||
}
|
||||
/// <summary>
|
||||
/// 指示此行为是否为模态行为。
|
||||
/// 返回值为 true,表示为模态行为,会阻止其他交互。
|
||||
/// </summary>
|
||||
public override bool IsModal => true;
|
||||
|
||||
/// <summary>
|
||||
/// 指示此行为是否会阻塞输入。
|
||||
/// 返回值为 true,表示会阻塞用户输入。
|
||||
/// </summary>
|
||||
public override bool BlocksInput => true;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user