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