From c931cb7d66d161c0347d95f1e2d8923016584be8 Mon Sep 17 00:00:00 2001 From: GeWuYou <95328647+GeWuYou@users.noreply.github.com> Date: Thu, 15 Jan 2026 12:33:19 +0800 Subject: [PATCH] =?UTF-8?q?feat(ui):=20=E6=B7=BB=E5=8A=A0CanvasItem?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E8=A1=8C=E4=B8=BA=E5=92=8CGodot=20UI?= =?UTF-8?q?=E5=B7=A5=E5=8E=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 实现CanvasItemPageBehavior类支持所有继承自CanvasItem的节点 - 添加OnEnter、OnExit、OnPause、OnResume、OnHide、OnShow页面生命周期方法 - 创建GodotUiFactory工厂类用于创建UI页面实例 - 实现Create方法根据UI键创建页面行为实例 - 重命名IUiPageProvider为IUiPageBehaviorProvider接口 - 更新接口方法GetPage返回页面行为实例的描述 --- .../ui/IUiPageBehaviorProvider.cs | 13 +++ .../ui/IUiPageProvider.cs | 13 --- GFramework.Godot/ui/CanvasItemPageBehavior.cs | 89 +++++++++++++++++++ GFramework.Godot/ui/GodotUiFactory.cs | 49 ++++++++++ 4 files changed, 151 insertions(+), 13 deletions(-) create mode 100644 GFramework.Game.Abstractions/ui/IUiPageBehaviorProvider.cs delete mode 100644 GFramework.Game.Abstractions/ui/IUiPageProvider.cs create mode 100644 GFramework.Godot/ui/CanvasItemPageBehavior.cs create mode 100644 GFramework.Godot/ui/GodotUiFactory.cs diff --git a/GFramework.Game.Abstractions/ui/IUiPageBehaviorProvider.cs b/GFramework.Game.Abstractions/ui/IUiPageBehaviorProvider.cs new file mode 100644 index 0000000..28b77b8 --- /dev/null +++ b/GFramework.Game.Abstractions/ui/IUiPageBehaviorProvider.cs @@ -0,0 +1,13 @@ +namespace GFramework.Game.Abstractions.ui; + +/// +/// UI页面行为提供者接口,用于获取页面行为实例 +/// +public interface IUiPageBehaviorProvider +{ + /// + /// 获取页面行为实例 + /// + /// 页面行为接口实例 + IPageBehavior GetPage(); +} \ No newline at end of file diff --git a/GFramework.Game.Abstractions/ui/IUiPageProvider.cs b/GFramework.Game.Abstractions/ui/IUiPageProvider.cs deleted file mode 100644 index d38892b..0000000 --- a/GFramework.Game.Abstractions/ui/IUiPageProvider.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace GFramework.Game.Abstractions.ui; - -/// -/// UI页面提供者接口,用于创建UI页面实例 -/// -public interface IUiPageProvider -{ - /// - /// 获取UI页面实例 - /// - /// UI页面实例 - IPageBehavior GetPage(); -} \ No newline at end of file diff --git a/GFramework.Godot/ui/CanvasItemPageBehavior.cs b/GFramework.Godot/ui/CanvasItemPageBehavior.cs new file mode 100644 index 0000000..bf2fa4c --- /dev/null +++ b/GFramework.Godot/ui/CanvasItemPageBehavior.cs @@ -0,0 +1,89 @@ +using GFramework.Game.Abstractions.ui; +using GFramework.Godot.extensions; +using Godot; + +namespace GFramework.Godot.ui; + +/// +/// 控制 UI 页面行为的泛型行为类, +/// 支持所有继承自 CanvasItem 的节点 +/// +/// CanvasItem 类型的视图节点 +public class CanvasItemPageBehavior(T owner) : IPageBehavior + where T : CanvasItem +{ + private readonly IUiPage? _page = owner as IUiPage; + + /// + /// 页面视图对象 + /// + public object View => owner; + + /// + /// 获取页面是否存活状态 + /// + public bool IsAlive => owner.IsValidNode(); + + /// + /// 页面进入时调用 + /// + /// 页面进入参数 + public void OnEnter(IUiPageEnterParam? param) + { + _page?.OnEnter(param); + } + + /// + /// 页面退出时调用 + /// + public void OnExit() + { + _page?.OnExit(); + owner.QueueFreeX(); + } + + /// + /// 页面暂停时调用 + /// + public void OnPause() + { + _page?.OnPause(); + + // 暂停节点的处理、物理处理和输入处理 + owner.SetProcess(false); + owner.SetPhysicsProcess(false); + owner.SetProcessInput(false); + } + + /// + /// 页面恢复时调用 + /// + public void OnResume() + { + _page?.OnResume(); + + // 恢复节点的处理、物理处理和输入处理 + owner.SetProcess(true); + owner.SetPhysicsProcess(true); + owner.SetProcessInput(true); + } + + /// + /// 页面隐藏时调用 + /// + public void OnHide() + { + _page?.OnHide(); + owner.Hide(); + } + + /// + /// 页面显示时调用 + /// + public void OnShow() + { + _page?.OnShow(); + owner.Show(); + OnResume(); + } +} \ No newline at end of file diff --git a/GFramework.Godot/ui/GodotUiFactory.cs b/GFramework.Godot/ui/GodotUiFactory.cs new file mode 100644 index 0000000..35f160c --- /dev/null +++ b/GFramework.Godot/ui/GodotUiFactory.cs @@ -0,0 +1,49 @@ +using GFramework.Core.extensions; +using GFramework.Core.utility; +using GFramework.Game.Abstractions.ui; +using Godot; + +namespace GFramework.Godot.ui; + +/// +/// Godot UI工厂类,用于创建UI页面实例 +/// 继承自AbstractContextUtility并实现IUiFactory接口 +/// +public class GodotUiFactory : AbstractContextUtility, IUiFactory +{ + /// + /// UI注册表,用于存储和获取PackedScene类型的UI资源 + /// + private IWritableUiRegistry _registry = null!; + + /// + /// 根据指定的UI键创建UI页面实例 + /// + /// UI资源的唯一标识键 + /// 实现IUiPage接口的UI页面实例 + /// 当UI场景没有继承IUiPage接口时抛出 + public IPageBehavior Create(string uiKey) + { + // 从注册表中获取对应的场景资源 + var scene = _registry.Get(uiKey); + + // 实例化场景节点 + var node = scene.Instantiate(); + + // 验证节点是否实现了IUiPageProvider接口 + if (node is not IUiPageBehaviorProvider provider) + throw new InvalidCastException( + $"UI scene {uiKey} must implement IUiPageBehaviorProvider"); + + // 获取并返回页面行为实例 + return provider.GetPage(); + } + + /// + /// 初始化方法,获取UI注册表实例 + /// + protected override void OnInit() + { + _registry = this.GetUtility>()!; + } +} \ No newline at end of file