diff --git a/GFramework.Game.Abstractions/enums/UiLayer.cs b/GFramework.Game.Abstractions/enums/UiLayer.cs index 1a91f33..b2cf363 100644 --- a/GFramework.Game.Abstractions/enums/UiLayer.cs +++ b/GFramework.Game.Abstractions/enums/UiLayer.cs @@ -9,25 +9,25 @@ public enum UiLayer /// /// 页面层,使用栈管理UI的切换 /// - Page = 0, + Page, /// /// 浮层,用于覆盖层、对话框等 /// - Overlay = 10, + Overlay, /// /// 模态层,会阻挡下层交互,带有遮罩效果 /// - Modal = 20, + Modal, /// /// 提示层,用于轻量提示如toast消息、loading指示器等 /// - Toast = 30, + Toast, /// /// 顶层,用于系统级弹窗、全屏加载等 /// - Topmost = 40 + Topmost } diff --git a/GFramework.Game.Abstractions/ui/IUiRoot.cs b/GFramework.Game.Abstractions/ui/IUiRoot.cs index 078caa8..ae0d84d 100644 --- a/GFramework.Game.Abstractions/ui/IUiRoot.cs +++ b/GFramework.Game.Abstractions/ui/IUiRoot.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using GFramework.Game.Abstractions.enums; namespace GFramework.Game.Abstractions.ui; @@ -17,8 +18,9 @@ public interface IUiRoot /// 向UI根节点添加子页面到指定层级 /// /// 要添加的UI页面子节点 - /// Z-order值,用于控制UI显示层级 - void AddUiPage(IUiPageBehavior child, int zOrder = 0); + /// 层级 + /// 层级内排序 + void AddUiPage(IUiPageBehavior child, UiLayer layer, int orderInLayer = 0); /// /// 从UI根节点移除子页面 @@ -38,9 +40,4 @@ public interface IUiRoot /// /// 所有显示的页面列表 IReadOnlyList GetVisiblePages(); - - /// - /// 强制刷新UI层级排序 - /// - void RefreshLayerOrder(); } \ No newline at end of file diff --git a/GFramework.Game/ui/UiRouterBase.cs b/GFramework.Game/ui/UiRouterBase.cs index a249ee7..c3ab761 100644 --- a/GFramework.Game/ui/UiRouterBase.cs +++ b/GFramework.Game/ui/UiRouterBase.cs @@ -504,7 +504,7 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter layerDict[uiKey] = page; // 添加到UiRoot,传入层级Z-order - _uiRoot.AddUiPage(page, (int)layer); + _uiRoot.AddUiPage(page, layer); page.OnEnter(param); page.OnShow(); @@ -526,7 +526,7 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter _layers[layer] = new Dictionary(); _layers[layer][uiKey] = page; - _uiRoot.AddUiPage(page, (int)layer); + _uiRoot.AddUiPage(page, layer); page.OnShow(); Log.Debug("Show existing UI instance in layer: {0}, layer={1}", uiKey, layer); diff --git a/GFramework.Godot/ui/GodotUiRoot.cs b/GFramework.Godot/ui/GodotUiRoot.cs index 7bcdaba..86411d2 100644 --- a/GFramework.Godot/ui/GodotUiRoot.cs +++ b/GFramework.Godot/ui/GodotUiRoot.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using System; +using GFramework.Game.Abstractions.enums; using GFramework.Game.Abstractions.ui; using Godot; @@ -20,6 +19,15 @@ public partial class GodotUiRoot : Node, IUiRoot /// UI页面的追踪字典,记录每个页面的节点 /// private readonly Dictionary _pageNodes = new(); + private static readonly IReadOnlyDictionary LayerZOrderMap = + new Dictionary + { + { UiLayer.Page, 0 }, + { UiLayer.Overlay, 100 }, + { UiLayer.Modal, 200 }, + { UiLayer.Toast, 300 }, + { UiLayer.Topmost, 400 }, + }; public override void _Ready() { @@ -44,11 +52,9 @@ public partial class GodotUiRoot : Node, IUiRoot if (node == null) throw new InvalidOperationException($"Page node is null: {child.Key}"); - if (_pageNodes.ContainsKey(child)) + if (!_pageNodes.TryAdd(child, node)) return; - _pageNodes[child] = node; - if (node.GetParent() != _uiContainer) { _uiContainer.AddChild(node); @@ -58,22 +64,26 @@ public partial class GodotUiRoot : Node, IUiRoot /// /// 向UI根节点添加子页面到指定层级 /// - public void AddUiPage(IUiPageBehavior child, int zOrder = 0) + public void AddUiPage( + IUiPageBehavior child, + UiLayer layer, + int orderInLayer = 0) { AddUiPage(child); - SetZOrder(child, zOrder); + + var z = GetBaseZOrder(layer) + orderInLayer; + SetZOrder(child, z); } + /// /// 从UI根节点移除子页面 /// public void RemoveUiPage(IUiPageBehavior child) { - if (!_pageNodes.TryGetValue(child, out var node)) + if (!_pageNodes.Remove(child, out var node)) return; - _pageNodes.Remove(child); - if (_uiContainer != null && node.GetParent() == _uiContainer) { _uiContainer.RemoveChild(node); @@ -101,17 +111,8 @@ public partial class GodotUiRoot : Node, IUiRoot { return _pageNodes.Keys.ToList().AsReadOnly(); } + - /// - /// 强制刷新UI层级排序 - /// - public void RefreshLayerOrder() - { - if (_uiContainer == null) - return; - - _uiContainer.MoveChild(_uiContainer.GetChild(0), 0); - } /// /// 从页面行为获取对应的节点 @@ -120,4 +121,8 @@ public partial class GodotUiRoot : Node, IUiRoot { return page.View as Node; } + private static int GetBaseZOrder(UiLayer layer) + { + return !LayerZOrderMap.TryGetValue(layer, out var z) ? throw new ArgumentOutOfRangeException(nameof(layer), layer, null) : z; + } }